java进阶---多态

多态的概述
什么是多态

同一个对象,在不同时刻表现出来的不同形态

多态的前提
  • 要有继承或实现关系
  • 要有方法的重写
  • 要有父类引用指向子类对象

多态的具体实现

对象的多态是多态的核心和重点

规则:
  • 一个对象的编译类型与运行类型可以不一致
  • 编译类型在定义对象时,就确定了,不能改变,而运行类型是可以变化的
  • 编译类型看定义对象=号的左边, 运行类型看=号的右边
代码演示
class Animal {
    public void eat(){
        System.out.println("动物吃饭");
    }
}

class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

public class Test1Polymorphic {
    /*
        多态的前提:

            1. 要有(继承 \ 实现)关系
            2. 要有方法重写
            3. 要有父类引用, 指向子类对象
     */
    public static void main(String[] args) {
        // 当前事物, 是一只猫
        Cat c = new Cat();
        // 当前事物, 是一只动物
        Animal a = new Cat();
        a.eat();

    }
}

多态中的成员访问特点

成员访问特点
  • 成员变量 :编译看父类,运行看父类
  • 成员方法 :编译看父类,运行看子类
代码演示
class Fu{
    int num=10;
    
    public void method(){
        System.out.println("Fu..method")
    }
}

class Zi extends Fu{
    int num=20;
    
    public void method(){
        System.out.println("Zi...method")
    }
}

public class Test{
    public static void main(String[] args){
        Fu f=new Zi();
        System.out.println(f.num);
        f.method();
    }
}
//输出:  10    Zi..method
多态的好处和弊端
好处

提高程序的扩展性,定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作

弊端

不能使用子类的特有成员

多态中的转型
向上转型

父类的引用指向子类对象就是向上转型

特点
  • 编译类型看左边,运行类型看右边
  • 可以调用父类的所有成员(须遵守访问权限)
  • 不能调用子类的特有成员
  • 运行效果看子类的具体实现
向下转型

一个已经向上转型的子类对象, 将父类引用转为子类引用

格式: 子类型 对象名 = (子类型) 父类的引用;

特点
  • 只能强制转换父类的引用,不能强制转换父类的对象
  • 要求父类的引用必须指向的是目标类型的对象
  • 当向下转型后,可以调用子类类型中所有的成员
代码演示
class Fu {
    public void show(){
        System.out.println("Fu..show...");
    }
}

class Zi extends Fu {
    @Override
    public void show() {
        System.out.println("Zi..show...");
    }

    public void method(){
        System.out.println("我是子类特有的方法, method");
    }
}

public class Test3Polymorpic {
    public static void main(String[] args) {
        // 1. 向上转型 : 父类引用指向子类对象
        Fu f = new Zi();
        f.show();
        // 多态的弊端: 不能调用子类特有的成员
        // f.method();

        // A: 直接创建子类对象
        // B: 向下转型

        // 2. 向下转型 : 从父类类型, 转换回子类类型
        Zi z = (Zi) f;
        z.method();
    }
}

多态中转型存在的风险和解决方案

风险

如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException

解决方案
关键字

instanceof

使用格式

变量名 instanceof 类型

通俗的理解: 判断关键字左边的变量,是否是右边的类型,返回Boolean类型结果

动态绑定

  • 当调用方法时,该方法会和该对象的运行内存绑定
  • 当调用对象属性时,没有动态绑定机制,即哪里声明,哪里使用

应用

多态数组

多态数组:数组的定义类型为父类类型,里面保存的实际元素为子类类型

代码演示
public class person{
    private String name;
    
    public Person(String name){
        this.name=name;
    }
    
    //get和set方法
    public String getName(){
        return name;
    }
    public Void setName(String name){
        this.name=name;
    }
    
    //mission()方法
    public String mission(){
        return name + "\t" + "做人要厚道";
    }
}

public class Student extends Person {
	private double score;

	public Student(String name, double score) {
		super(name);
		this.score = score;
	}

	public double getScore() {
		return score;
	}

	public void setScore(double score) {
		this.score = score;
	}
	
	//重写父类的say方法
	@Override
	public String mission() {	
		return super.mission() + " score =" + score + " 要好好学习!";
	}
}

public class Teacher extends Person {
	private double salary;

	public Teacher(String name, double salary) {
		super(name);
		this.salary = salary;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}
	
	//重写父类的 mission 方法
	@Override
	public String mission() {	
		return super.mission() + " salary =" + salary + " 要好好教书!";
	}
}
//开始演示多态数组
//创建一个Person对象
//创建一个Student对象
//创建一个Teacher对象
//统一放在数组里 并调用每个对象的missio()方法

public class Arr{
    public static void main(String [] args){
        Person[] persons = new Person[3];
        Persons[0] = new Person("小白");
        Persons[1] = new Student("小王",12);
        Persons[2] = new Teacher("老黑",1000);
        
        //循环遍历多态数组
        for(int i; i < Persons.length; i++){
            //此位置涉及动态绑定机制
            //Persons[i]编译类型是Person , 运行类型根据实际情况由JVM判断
            System.out.prinln(Persons[i].mission())
        }
    }
}

//运行结果
小白	做人要厚道!
小王	做人要厚道! score = 12 要好好学习!
老黑	做人要厚道! salary = 1000 要好好教书!

多态参数

方法定义的形参类型为父类类型,实参类型允许为子类类型

代码演示
//演示多态参数
public class PolyParameter { 
	public static void main(String[] args) {
		Student s1 = new Student("小蓝同学");
		Teacher t1 = new Teacher("小绿老师");
		
		//需先 new 一个当前类的实例化,才能调用 test 方法
		PolyParameter polyParameter = new PolyParameter();
		
		//实参是子类
		polyParameter.test(s1);
		polyParameter.test(t1);		
	}

	//定义方法test,形参为 Person 类型(形参是父类)
	//功能:调用学生的study或教师的teach方法
	 public void test(Person p) {
        if (p instanceof Student){
            ((Student) p).study();   //向下转型
        }
        else if (p instanceof Teacher){
            ((Teacher) p).teach();  //向下转型
        }  
	 }
}
 
//父类
class Person {
	private String name;
	
	//有参构造
	public Person(String name) {
		this.name = name;
	}
	
	// getter 和 setter
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

//子类
class Student extends Person {

	public Student(String name) {
		super(name);
	}

	// study() 方法
	public void study() {	
		System.out.println(super.getName() + "\t" + "正在好好学习");
	}
}

class Teacher extends Person {

	public Teacher(String name) {
		super(name);
	}

	// teach() 方法
	public void teach() {	
		System.out.println(super.getName() + "\t" + "正在好好教书");
	}
}

//运行结果
小蓝同学	正在好好学习
小绿老师	正在好好教书

你可能感兴趣的:(实战班,java,开发语言)