抽象与接口
抽象
在之前的学习中,由于多态,子类都可以重写父类的方法
class Person {
public void run() { … }
}
class Student extends Person {
@Override
public void run() { … }
}
class Teacher extends Person {
@Override
public void run() { … }
}
如果父类的方法没有实际的意义,能直接去掉执行语句嘛
class Person {
public void run() {
}
}
答案是不行!会报错
那么可以删去run方法嘛?
class Person {
}
也是不行,这样我们就失去了多态的特性。
如果父类的方法本身没有意义,只是为了让子类去重写,我们可以用到abstract关键字
abstract class Person {
public abstract void run();
}
由于抽象化方法无法被引用,因此这个类也无法被实例化,类也需要转变为抽象类abstract class。
接口
当一个抽象类没有字段且方法全是抽象方法时
abstract class Person {
public abstract void run();
public abstract void speak();
}
我们就可以吧抽象类更改为接口:interface
我们可以这么声明一个接口
interface Person {
void run();
String getName();
}
我们可以用一个具体的class类去实现interface接口:
interface Person {
void run();
String getName();
// String getsName();
}
class Student implements Person {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(this.name + " run");
}
@Override
public String getName() {
return this.name;
}
}
当然,接口可以实现多继承
class Student implements Person, Hello {
...
}
接口继承
一个接口可以继承另一个接口,接口之间继承用extends关键字
interface Hello {
void hello();
}
interface Person extends Hello {
void run();
String getName();
}
default 方法
当我们需要修改或者新增一个新的方法,如果我们直接去修改,所有子类必须同时修改,这时我们可以用default去修饰新的方法,需要更改的子类去重写即可
interface Person {
String getName();
default void run() {
System.out.println(getName() + " run");
}
}
注释与说明
- 此处用static修饰也能起到相同作用
- 由于多继承,如果一个类由a,b两个接口所实现且有相同标签名的default方法,则必须重写方法。
面向抽象编程
引用高层类型,避免引用实际子类型的方式,称之为面向抽象编程。
-
面向抽象编程的本质就是:
-
- 上层代码只定义规范(例如:abstract class Person);
-
- 不需要子类就可以实现业务逻辑(正常编译);
-
- 具体的业务逻辑由不同的子类实现,调用者并不关心。