【JAVASE_学习笔记】多态
多态指一个对象具备多种形态
多态的前提:
1.必须存在继承或者实现关系
2.父类引用类型变量指向了子类的对象或是接口的引用类型变量指向了接口实现类对象
3.必须有方法重写
注意:
1.多态情况下,子父类存在着同名的成员变量时,默认会访问父类的成员变量
2.多态情况下,子父类存在同名的非静态方法时,默认是访问子类的成员方法
3.多态情况下,子父类存在同名静态方法时,默认是访问父类的成员变量
总结:多态情况下,子父类存在同名成员时,默认访问父类成员,只有存在非静态同名方法时,才访问子类成员
4.多态情况下,不能访问子类特有成员
向上转型与向下转型:
向上转型:父类引用类型变量指向子类的对象
向下转型:将父类的引用强制转换为子类的引用,前提必须有父类的引用存在,向下转型必须依赖于向上转型。
多态的好处(特点):
1)提高代码的维护性(由继承保证)
2)提高代码的扩展性(由多态保证)
多态的弊端:
不能访问子类的特有功能
多态的应用场景:
1.多态用于形式参数类型时,可以接收更多类型参数
形参为抽象类:抽象类多态
//形参为抽象类
public class Demo3 {
public static void main(String[] args) {
School s=new School();
Student1 s1=new EnglishStudent();//用抽象类多态来进行实例化,非静态同名方法访问子类方法
s.method(s1);
//或者链式编程
s.method(new EnglishStudent());
}
}
abstract class Student1{
public abstract void study();
}
class EnglishStudent extends Student1{
public void study() {
System.out.println("学习英语");
}
}
class School{
public void method(Student1 s){//形参运用抽象类多态
s.study();
}
}
形参为接口:接口多态
//形参为接口
public class Demo4 {
public static void main(String[] args) {
BirdDemo bd=new BirdDemo();
Swimming b=new Bird();//接口多态,非静态同名方法访问子类方法
bd.method(b);
//链式编程
bd.method(new Bird());
}
}
interface Swimming{
public abstract void swimming();
}
class Bird implements Swimming{
public void swimming(){
System.out.println("一些鸟能入水");
}
}
class BirdDemo{
public void method (Swimming s){
s.swimming();
}
}
2.多态用于返回值类型时,可以返回更多类型的参数
返回值为抽象类:抽象类多态
// 抽象类多态
public class Demo1 {
public static void main(String[] args) {
Cat c=new Cat();
c.method().eat();//猫吃鱼
}
}
abstract class Animal{
public abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
//运用匿名对象和抽象类多态
public Animal method(){
return new Cat();//返回抽象类的子实现类
}
}
返回值为接口:接口多态
//接口多态
public class Demo2 {
public static void main(String[] args) {
Student s =new Student();
s.method().speakEnglish();
}
}
interface English{
public abstract void speakEnglish();
}
class Student implements English{
public void speakEnglish(){
System.out.println("这是英语流利的学生");
}
//接口多态
public English method(){
return new Student();//返回接口的子实现类对象
}
}
多态情况下如果需要调用到子类特有成员,需强制类型转换(向下转型)
这是为了避免出现OOM异常
严重:OutOfMemory 内存溢出
举例:
Animal a = new Fish();
Fish f =(Fish) a;
容易出现强制类型转换异常:ClassCastException
引用类型变量做强制类型转换之前一般都会使用instanceof先判断
instanceof关键字
判断一个对象是否属于指定的类型
使用前提:判断的对象与指定的类型必须存在继承或者实现关系
格式:对象 instanceof 类名
举例:
public class Demo1 {
public static void main(String[] args) {
Dog d=new Dog();
System.out.println("狗属于动物类么"+(d instanceof Animal));//狗属于动物么true
//System.out.println("狗属于猫类么"+(d instanceof Cat));//报错
Animal a=new Animal();
System.out.println("动物是属于狗类么"+(a instanceof Dog));//动物是属于狗类么false
}
}
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}