多态:接口的多种不同实现方式。
多态必须满足的三大条件:
1、继承
2、必须有方法的重写
3、向上转型,使用父类的方法,通过动态绑定机制实现子类的方法实现,可以减少子类对父类某个方法的重复重写。
动态绑定机制:java提供一种动态绑定机制。在运行期判断对象类型,并分别调用适当的方法。
public class Shape {
public void draw(){
System.out.println("Shape draw");
}
}
public class Circle extends Shape {
public void draw(){
System.out.println("Circle draw");
}
}
public class Square extends Shape{
public void draw(){
System.out.println("Sqaure draw");
}
}
public class ShapeMain {
public static void main(String[] args) {
Shape shape_c = new Circle(); //向上转型
Shape shape_s = new Square(); //向上转型
//动态绑定
shape_c.draw();
shape_s.draw();
}
}
输出结果:
Circle draw
Sqaure draw
ShapeMain类,看似是Shape的句柄调用了draw()方法,但因为java的动态绑定机制,所以能正确识别对象的类型,正确调用了对象的draw方法。
抽象类和抽象方法:
1、一个类包含了抽象方法的类叫抽象类。只要一个类里有一个抽象方法,则这个类就必须定义为抽象类,否则编译器报错。
public class Shape { //编译器报错,The abstract method draw in type Shape can only be defined by an abstract class
public abstract void draw();
public void clear(){};
}
2、即使一个类不包含抽象方法,也可以将它定义为抽象类,可以禁止那个类的所有实例。
public abstract class Shape {
}
3、一个抽象类里可以包含抽象方法和非抽象方法,可以抽象方法是0个。
public abstract class Shape {
public void draw(){};
public void clear(){};
}
4、因为抽象方法是不完整的,所以不能将一个抽象类实例化。
5、如果子类继承父类,则子类需实现父类的所有抽象方法,也可以不实现,如果有部分不实现,则子类也需定义成抽象类。
接口:更深一层的抽象
关键字:interface
定义一个接口:
public interface IShape {
public void draw();
public void clear();
}
定义的接口的方法默认都是public且是抽象的abstract
public class zhengfangxing implements IShape{
//编译报错:The type zhengfangxing must implement the inherited abstract method IShape.clear()
public void draw() {
System.out.println("正方形 draw");
}
}
如果一个普通的class实现了一个接口,则必须实现接口的所有方法,否则会编译报错。
public class zhengfangxing implements IShape{
public void draw() {
System.out.println("正方形 draw");
}
public void clear() {
// TODO Auto-generated method stub
}
}
或者可以将该类改成抽象类,对部分方法暂不予实现。
public abstract class zhengfangxing implements IShape{
public void draw() {
System.out.println("正方形 draw");
}
}
接口和抽象之间的关系:
1、抽象类可以有部分非抽象方法,部分抽象方法。在子类继承抽象类的时候,若抽象类可以加入新的方法则子类同时也可以继承新的方法。
接口是只能定义抽象方法,如果要拓展接口则实现接口的具体类都会编译出错(没有实现抽象类),不便于接口拓展。
2、抽象类是个类,只能单继承;接口可以多实现。
public class zhengfangxing extends Shape implements IShape{
public void draw() {
System.out.println("正方形 draw");
}
}
3、接口是定义混合型类的理想工具,可以实现多实现。
4、缺省适配器模式(设计模式):
为了同时利用接口的多实现和抽象类的便于拓展的特性,可以先定义一个接口,然后用一个抽象类实现这个接口。
真正的具体类既继承了抽象类也实现了接口,这样既可以多实现也可以便于拓展。
在结构层次上说,是接口=>抽象类
//定义一个接口
public interface IShape {
public void draw();
public void clear();
}
//抽象类实现接口
public abstract class Shape implements IShape{
public abstract void draw();
public void clear(){
System.out.println("Shape Clear");
};
public void chage(){
System.out.println("chage");
}
}
//具体类继承抽象类和实现接口
public class Square extends Shape implements IShape{
public void draw(){
System.out.println("Sqaure draw");
}
public void clear(){
System.out.println("Sqaure Clear");
};
}
有单继承,多实现的概念
接口可以通过继承生成新的接口,接口继承的话可以多继承:
public interface Interface1 {
public void f1();
}
public interface Interface2 extends Interface1 {
public void f2();
}
public interface Interface3 extends Interface1, Interface2{
public void f3();
}
接口中定义的字段:
接口中定义的字段具有final static的属性。因为是静态的,所以类一加载就为字段分配内存,并且初始化。