多态前提:
- 要有继承关系
- 要有方法重载
- 要有父类对象引用子类对象 Father f = new Son()
成员变量 f.name:编译看左边(父类),运行看左边(父类)(因为f还是属于Father)
成员方法 f.print():编译看左边(看父类有没有这个方法,若没有,会报错,,如果父类有,子类没有,就直接用父类的),运行看右边(子类)(也叫动态绑定)
静态成员方法:其实静态成员方法算不上是重写了,因为静态成员和类一起加载到方法区,可以直接用类名.方法名来调用,所以编译看左边,运行也看左边
代码如图:
public class LongTest {
public static void main(String[] args) {
Father f = new Son();
System.out.println(f.num);
f.print();
Son s = new Son();
System.out.println(s.num);
s.print();
}
}
class Father{
int num = 10;
public void print() {
System.out.println("father");
}
}
class Son extends Father{
int num = 20;
public void print() {
System.out.println("son");
}
}
java多态好处:提高了代码得维护性(继承保证),提高了代码得扩展性(多态保证)
java多态弊端:不能使用子类特有得属性和方法(要有父类对象引用子类对象得时候,如果**f.print()**在父类中没有定义,那么就会报错)
所以在已经向上转型之后可以来个向下强转
向上转型/向下转型:
向上转型:
Father f = new Son();
向下转型:
Son son = (Son)f
关键字:instanceof: 判断前面得引用是否是后面的数据类型
if(a instanceof Cat){
...
}else if(a instanceof Dog){
...
}else{
...
}
抽象类(abstact):
- 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或是接口
- 抽象类不能实例化,可由具体的子类实例化
- 抽象类的子类:要么也是抽象类,要么重写抽象类中所有的抽象方法
抽象类的成员特点:
- 成员变量:既可以是变量,也可以是常量,不能用abstrat修饰
- 构造方法:有,用于子类访问父类构造函数并初始化(super())
- 成员方法:既可以是抽象的(强制子类做的),也可以是非抽象的(子类继承过去的)
abstract不能和那些关键字共存:
- static: abstract不能和static共存,因为abstract没有方法体,而static可以用类名直接调用,这么一来就没有意义了
- finna: abstract不能和finnal共存,一个要重写,一个不能重写
- private: abstract不能和private共存,abstract是要被子类看到并重写,而private不能让子类看到
接口(interface):
接口的成员特点:
- 成员变量:只能是变量,并且是静态和公共的(默认 public static finnal )
- 接口中的方法都是抽象的(默认 public abstract)
- 接口中没有构造方法,一个类默认继承的是Objec t类
类与类: 继承关系,单继承,可以多层继承
类于接口: 实现关系,可以单实现,也可以多实现
接口和接口: 继承关系,可以单继承,也可以多继承
抽象类与接口:
抽象类(is a,定义的是共性功能):其实和普通类一样,只是可以定义抽象方法
接口(like a,定义的是扩展功能):属性只能是常量,方法只能是抽象