目录
- 满足多态的条件
- 动态绑定第一步
- 动态绑定第二步
- 动态绑定第三步
- 参数列表,返回类型,访问修饰限定符区别
- 有动态绑定,那是不是有静态绑定
- 向下转型
- 抽象类
- 接口
- 实现多个接口(先继承再接口,接口用",")
满足多态的条件
定义:去完成某个状态的时候,当不同的对象去完成的时候会产生不同状态(通俗理解为看人下菜)
满足多态的条件:
1>必须在继承关系上,才可以向上转型
2>子类和父类有同名的覆盖(重写)方法
3>通过父类对象的引用,去调用这个重写的方法
完成以上的三个部分,就会发生动态绑定,动态绑定为多态的基础
通过父类的引用,只能调用父类自己独有的属性,方法,构造方法
动态绑定第一步
向上转型:子类定义的变量,方法给父类
Dog dog = new Dog("小黄",8);
Animal animal = dog;
Animal animal = new Dog("小黄", 8);
这个被称为直接赋值型
是通过animal这个引用指向了dog这个引用所指向的对象
传参时候进行向上转型(方法的参数)
public static void func1(Animal animal){}
public static void main(String [ ] args){Dog dog = new Dog("小黄",8);func1(dog);
}
返回值进行向上转型
public static Animal func2( ){Dog dog = new Dog("小黄", 8);return dog;
}
动态绑定第二步
public static Animal func2( ){System.out.println(this.name + "吃饭");
}
@Override(可以在此写注释,起到防止错误作用)
public void eat( ){System.out.println(this.name + "吃狗粮");
}
注意:
1>在这里面,返回值,方法名以及参数链表要相同
2>被重写的访问修饰限定符,子类一定要大于父类
3>被private修饰的方法不可重写
4>被static修饰的方法不可以重写
5>被final修饰的方法不可重写
6>构造方法不可以重写
动态绑定第三步
Animal animal = new Dog("小黄",8);
animal eat( );
在产生了重写以后,animal忽然就变成了调用子类的eat.这个过程就叫做动态绑定
父类与子类也可以构成重写,被称为协变类型
public Dog eat( ){System.out.println(this.name + "吃饭");return null;
}
public Animal eat( ){System.out.println(this.name + "吃狗粮");
}
所有的父类,默认都是Object类
public static void eatFun(Animal animal){animal.aet( );
}
public static void main(String [ ] args){Dog dog = new Dog("小黄", 8);eatFun(dog);Cat cat = new Cat("三月",6);eatFun(cat);
}
当父类的引用,引用的子类对象不一样的时候,调用这个重写的方法,表现出的行为是不一样的,我们把这种思想叫做多态
参数列表,返回类型,访问修饰限定符区别
有动态绑定,那是不是有静态绑定
add(int a, int b)
add(int a, int b, int c)
main( ){add(1, 2);add(1, 2 ,3);
}
这上面这种就是静态绑定
向下转型
顾名思义,就是父类给子类
Animal animal = new Dog("小黄", 8 );
//狗可以为一个动物
Animal animal = new Cat ("三月", 6);
//猫也可以为一个动物Animal animal = new Dog("小黄", 8 );
Dog dog = animal;
//但是在这个里面,动物不一定是狗,
//所以向下转型是不安全的Animal animal = new Dog ("小黄", 8 );
Dog dog = (Dog) animal;
//因为本身不安全的,所以这里要进行强转
dog.bark( );Cat cat = (Cat)animal;
cat.miaomaio( );
//这里的话就会错,因为animal在上面是引用对象为Dog,
//所以dog可以成功转型,Cat就不可以
在父类的构造方法里面,可以调用子类和父类重写的方法,此时会调用子类的方法,此时也会发生动态绑定,但是注意,不可以这么写
抽象类
abstract class Shape{public abstract void draw( );
}
1>abstract修饰的类,方法为抽象类(方法)
2>抽象类不可以实例化一个对象
3>抽象类中可以和普通类一样,定义方法和变量
4>当一个普通类继承了抽象类,那么要重写这个抽象类中的抽象方法
5>抽象类的出现就是为了被继承
6>abstract 和 final 是天敌,不可以共存
7>被private static 修饰的这个抽象方法也不可以
接口
语法:
1>interface方法来修饰的(就是创建方法时候,把class换成interface)
2>接口中不可以被实现的方法,只有抽象方法(static , deafult修饰的不受限制)
3>接口中的抽象方法,默认都是public abstarct 修饰的
4>接口中的成员变量,默认都是public static final修饰的
5>接口不能进行实例化
6>类和接口之间的关系,可以使用implements来进行关联
7>接口也有对应的字节码文件
注意:
1>接口中的方法不可以在接口中实现,只能由实现接口的类来实现
2>接口中不能包含构造方法,以及静态代码块
实现多个接口(先继承再接口,接口用",")
interface A{void test A( );
}
interface B extends A{void test B( );
}
这个里面的话,B也具备了A的功能,但是后面用接口B的时候,B和A都要重新实现
2个关系
1>类与接口之间的关系,用implements
2>接口与接口之间的关系,用extends