抽象类
- 抽象方法 : 没有方法体的方法。
- 抽象类:包含抽象方法的类
public abstract void 方法();
抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。
继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。抽象类不能创建对象,只能创建其非抽象子类的对象。
// 父类,抽象类
abstract class Employee {
private String id;
private String name;
private double salary;
public Employee() {
}
public Employee(String id, String name, double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
// 抽象方法
// 抽象方法必须要放在抽象类中
abstract public void work();
}
// 定义一个子类继承抽象类
class Manager extends Employee {
public Manager() {
}
public Manager(String id, String name, double salary) {
super(id, name, salary);
}
// 2.重写父类的抽象方法
@Override
public void work() {
System.out.println("管理其他人");
}
}
// 定义一个子类继承抽象类
class Cook extends Employee {
public Cook() {
}
public Cook(String id, String name, double salary) {
super(id, name, salary);
}
@Override
public void work() {
System.out.println("厨师炒菜多加点盐...");
}
}
// 测试类
public class Demo10 {
public static void main(String[] args) {
// 创建抽象类,抽象类不能创建对象
// 假设抽象类让我们创建对象,里面的抽象方法没有方法体,无法执行.所以不让我们创建对象
// Employee e = new Employee();
// e.work();
// 3.创建子类
Manager m = new Manager();
m.work();
Cook c = new Cook("ap002", "库克", 1);
c.work();
}
}
接口
接口是更加彻底的抽象,JDK7之前,包括JDK7,接口中全部是抽象方法。接口同样是不能创建对象的。
//接口的定义格式:
interface 接口名称{
// 抽象方法
}
// 接口的声明:interface
// 接口名称:首字母大写,满足“驼峰模式”
内部类
成员内部类
类定义在了成员位置 (类中方法外称为成员位置,无static修饰的内部类)
方式一:外部直接创建成员内部类的对象
外部类.内部类 变量 = new 外部类().new 内部类();
方式二:在外部类中定义一个方法提供内部类的对象
方式一:
public class Test {
public static void main(String[] args) {
// 宿主:外部类对象。
// Outer out = new Outer();
// 创建内部类对象。
Outer.Inner oi = new Outer().new Inner();
oi.method();
}
}
class Outer {
// 成员内部类,属于外部类对象的。
// 拓展:成员内部类不能定义静态成员。
public class Inner{
// 这里面的东西与类是完全一样的。
public void method(){
System.out.println("内部类中的方法被调用了");
}
}
}
方式二:
public class Outer {
String name;
private class Inner{
static int a = 10;
}
public Inner getInstance(){
return new Inner();
}
}
public class Test {
public static void main(String[] args) {
Outer o = new Outer();
System.out.println(o.getInstance());
}
}
编写成员内部类的注意点:
- 成员内部类可以被一些修饰符所修饰,比如: private,默认,protected,public,static等
- 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
- 创建内部类对象时,对象中有一个隐含的Outer.this记录外部类对象的地址值。
详解:
内部类被private修饰,外界无法直接获取内部类的对象,只能通过方式二获取内部类的对象
被其他权限修饰符修饰的内部类一般用方式一直接获取内部类的对象
内部类被static修饰是成员内部类中的特殊情况,叫做静态内部类(下面2
内部类如果想要访问外部类的成员变量,外部类的变量必须用final修饰,JDK8以前必须手动写final,JDK8之后不需要手动写,JDK默认加上。
静态内部类
类定义在了成员位置 (类中方法外称为成员位置,有static修饰的内部类)
静态内部类特点:
- 静态内部类是一种特殊的成员内部类。
- 有static修饰,属于外部类本身的。
- 总结:静态内部类与其他类的用法完全一样。只是访问的时候需要加上外部类.内部类。
- 拓展1:静态内部类可以直接访问外部类的静态成员。
- 拓展2:静态内部类不可以直接访问外部类的非静态成员,如果要访问需要创建外部类的对象。
- 拓展3:静态内部类中没有银行的Outer.this。
局部内部类
类定义在方法内
匿名内部类
没有名字的内部类,可以在方法中,也可以在类中方法外。
new 父类名或者接口名(){
// 方法重写
@Override
public void method() {
// 执行语句
}
};
对接口实现,对类继承,需要重写所有抽象方法,相当于创建只用一次的对象(没有名字
使用步骤:定义子类;重写方法;创建对象;调用方法
以接口为例:
interface Swim {
public abstract void swimming();
}
public class Demo07 {
public static void main(String[] args) {
// 使用匿名内部类
new Swim() {
@Override
public void swimming() {
System.out.println("自由泳...");
}
}.swimming();
// 接口 变量 = new 实现类(); // 多态,走子类的重写方法
Swim s2 = new Swim() {
@Override
public void swimming() {
System.out.println("蛙泳...");
}
};
s2.swimming();
s2.swimming();
}
}
可以将匿名内部类当作参数进行传递
goSwimming(new Swim() {
public void swimming() {
System.out.println("小学生, 自由泳...");
}
});