Java-多态
1、什么是多态
- 多态就是多种形态,同一个动作作用于不同的对象产生不同的行为
- 多态性,可以理解为一个事物的多种表现形态。在Java中有两种体现:
- 方法的重载(overload)和重写(overwrite)
- 子类对象的多态性(可以直接应用在抽象类和接口上)
- 对象的多态性指一个对象多种形态;在Java中,子类的对象可以替代父类的对象使用
形成多态的必要条件:
- 继承:存在子类和父类的关系
- 接口实现:定义一个类实现对应的接口
- 重写:子类重写了父类的方法
- 重载:调用相同的方法名,实现的功能时不一样
- 子类对象的多态性(重点):父类的引用指向子类的实例
2、两种多态性
-
编译时多态性
对于多个同名方法,如果在编译时能够确定执行同名方法中的哪一个,则称为编译时多态性。(编译时看左边)
-
运行时多态性
如果在编译时不能确定,只能在运行时才能确定执行多个同名方法中的哪一个,则称为运行时多态性。(运行时看右边)
3、对象的转型
对象转型分为:
- 向上转型:将子类对象交给父类引用,可以自动转换,如:Pet pet1=new Dog(“小白”, “泰迪”);
- 向下转型:把父类转成子类 强制类型转换,如:Dog dog1=(Dog) pet1;
instanceof运算符:
- 该运算符用来判断一个对象是否属于一个类或者实现了一个接口,结果为true或false
- 在强制类型转换之前通过instanceof运算符检查对象的真实类型,可以避免类型转换异常,从而提高代码健壮性
例如:
public void play(Pet pet){
//instanceof:用于判断类型是否匹配
if(pet instanceof Dog){ //判断父类pet是否属于子类对象Dog的实例
Dog dog=(Dog)pet;
dog.catchingFlyDisc();
dog.info();
}else if(pet instanceof Penguin){
Penguin p=(Penguin)pet;
p.swimming();
p.info();
}
}
4、final 关键字
- final修饰的类不能被继承。提高安全性,提高程序的可读性。
- final修饰的方法不能被子类重写。
- final修饰的属性为常量。一旦初始化后,不可再被赋值。习惯上,常量用大写字符表示。
- final标记的成员变量必须在声明的同时或在每个构造方法中或代码块中显式赋值,然后才能使用。
- 比如:final double PI=3.14;
- 若变量用static final修饰:全局常量。比如:Math 类的PI
5、static关键字
使用范围:
- 在Java类中,可用static修饰属性、方法、代码块、内部类
被修饰后的成员具备以下特点:
- 随着类的加载而加载
- 优先于对象存在
- 修饰的成员,被所有对象所共享
- 访问权限允许时,可不创建对象,直接被类调用
类变量
- 由类创建的所有的对象,都共用这一个属性
- 当其中一个对象对类变量进行更改以后,其他对象的这个类变量也会更改
- 类变量随着类的加载而加载的,而且独一份
- 静态的变量可以直接通过 “类.类变量” 的形式来调用
- 类变量的加载是要早于对象。所以当有对象以后,可以“对象.类变量”使用。但是"类.实例变量"是不行的。
- 类变量存在于静态域中。
类方法
通常的方法都会涉及到对具体对象的操作。这些方法在调用时,需要隐式的传递对象的引用。
没有对象的实例时,可以用类名.方法名()的形式访问static标记的类方法。
- 在静态方法里只能直接调用同类中其它的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。
- 静态方法不能以任何方式引用this关键字。因为静态方法在使用前不用创建任何实例对象,当静态方法被调用时,this所引用的对象根本就没有产生。
- main() 方法是静态的,因此JVM在执行main方法时不创建main方法所在的类的实例对象,因而在main()方法中,我们不能直接访问该类中的非静态成员。
类属性、类方法的作用
- 随着类的加载而加载,只加载一次
- 类属性作为该类各个对象之间共享的变量。
- 在设计类时,分析哪些类属性不因对象的不同而改变,将这些属性设置为类属性。
- 如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。
静态初始化
- 一个类中可以使用不包含在任何方法体中的静态代码块。当类被载入时,静态代码块被执行,且只被执行一次。静态块经常用来进行类属性的初始化。
- static块通常用于初始化static(类)属性