ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

2022-07-25 第4组 蒋萍 Java面向对象(5)多态基础

2022-07-25 20:02:09  阅读:107  来源: 互联网

标签:25 Java 子类 dog 多态 Dog 抽象类 父类 方法


Java面向对象之多态基础

目录

image

1、怎么理解多态?

  • 同一方法可以根据发送对象的不同而采用多种不同的行为方式

  • 同一事物,由于条件不同,产生的结果也不同

  • 同一引用类型,使用不同实例时,执行不同的操作而呈现不同的结果

多态是方法的多态(不是属性!)

子类重写了父类的方法,执行子类的方法

1.1 多态实现条件

  1. 有继承关系;

  2. 方法重写;

  3. 父类引用指向子类实例(子类对象);

    Pet pet = new Dog();

    对象能执行哪些方法,主要看对象左边的类

1.2 不可重写的:

  • static方法,属于类,不属于实例

  • final 常量,不可重写

  • private方法,私有的不可重写

子类继承父类,子类进行方法重写,父类引用指向子类对象,执行相应子类方法。


父类有一个和子类一样的方法,但父类没有具体的实现,但在不同子类中,各子类有各自的实现方法;此时父类也就是没有方法体的,我们把它定义为抽象类


// 父类方法
public void eat(){
        // 无方法体——> 抽象方法
    }

就等同于

public abstract void eat();// 抽象方法

父类的抽象方法一定要在子类实现:

2、 抽象类的使用特点

  1. 一个方法没有方法体(有这个行为,但没有具体实现)时,就叫抽象方法,给该方法加上 abstract 即可;
  2. 有抽象方法的类一定是抽象类,反之抽象类里面可以有抽象方法页可以没有(为后面程序扩展做准备);
  3. 抽象类不可实例化本类对象:A a = new A(),可以作引用类型,创建子类对象(子类不是抽象类);
  4. 抽象类的子类可以是普通类,该普通类一定要实现抽象类中的抽象方法;
  5. 抽象类的子类也可以是抽象类,此时父类中的抽象方法在子类中可以不被实现;

抽象类中,可以有构造方法 ,是供子类创建对象时,初始化父类成员使用的。

3、 多态的使用:

// Pet父类——> 抽象类
public abstract class Pet {
   // …………
    public abstract void eat();// 父类的抽象方法
    // 可理解为子类都有的方法,但父类没法统一实现
}
// 子类是普通类
public class Dog extends Pet {
    
    // 子类重写父类的 eat()
    public  void eat(){
        if (this.getHealth()==100){
            System.out.println("狗狗"+this.getName()+"吃饱了,无需喂食");
        }else{
            System.out.println("需要吃骨头");
            this.setHealth(this.getHealth()+3);
            //进食后健康值+3
        }   
}
public class Master {
    // 主人给宠物喂食
    public void feed(Pet pet){// 需要父类引用类型
        pet.eat();
    }
}
// 测试类
public static void main(String[] args) {
    
		Master master = new Master();
        master.feed(dog);// 指向子类实例——> 调相应的eat方法
    
}

4、向上转型

// 测试类
// 上面的代码段变成这样,发现效果也是一样的~
public static void main(String[] args) {
    
        Pet dog=new Dog("多多",40); //父类类型指向子类对象 **
        dog.eat();
    	 // …………
 }
  • 向上转型:

父类引用指向子类对象,自动进行类型转换;

4.1 note:

  1. <父类型> <引用变量名> = new <子类型>

  2. 此时通过父类引用变量调用的方法是子类覆盖或继承父类方法,不是父类的方法;

    这就可以解释为什么在父类中方法没有具体实现了

  3. 此时通过父类引用变量无法调用子类特有的方法

    这就是前面提到的 “ 对象能执行哪些方法,主要看对象左边的类 ”

那 就想调子类特有的方法 怎么办???

5、向下转型

// 狗狗独有方法
    public void catchfly(){
        System.out.println("狗狗可以刁飞碟");
    }
// 测试类
Pet dog=new Dog("多多",40);
// dog.catchfly();——> 报错
Dog d = (Dog)dog;
// ——> 强制转换:// 将父类 Pet 类型强制转为子类Dog 类型

d.catchfly(); // 执行子类Dog 类特有的方法
  • 向下转型:

将一个指向子类对象的父类引用赋给一个子类引用:父类类型转换为子类类型,进行强制转换

5.1 note:

  1. < 子类型 > < 引用变量 > = <子类型>< 父类型的引用变量 >
  2. 在向下转型过程中,如果没有转换为真实子类类型,会出现类型转换异常;
Pet dog=new Dog("多多",40);
Penguin p=(Penguin)dog
 // 真实子类类型是狗狗

// 编译通过了,但

// 运行时报错:Exception in thread "main" java.lang.ClassCastException:

5.2 ClassCastException(类型转换错误

//改正:    
Pet penguin=new Penguin("Q仔",60);
Penguin p=(Penguin)penguin
 p.swim();// 调用 Penguin 类特有的swim()

那如何避免这个问题 ???

我们加个判断;

5.3 instanceof 运算符

// 测试类
 Pet dog=new Dog("多多",40);
if (dog instanceof Dog){
	Dog d = (Dog)dog;
	d.catchfly();
}else if( dog instanceof Penguin ){
    Penguin p=(Penguin)dog;
    p.swim();
}

注意:使用instanceof 时,对象的类型必须和instanceof 后面的参数所指定的类在继承上有上下级关系。

6、 总结

  • 抽象类和抽象方法特点:

    • 抽象类不能直接实例化,它只能作为其他类的父类;

    • 抽象方法只有声明,不能具体实现;

  • 定义抽象类意义所在 :

    • 为其子类提供一个公共类型(父类引用指向子类实例);

    • 封装子类重复内容(成员变量和方法)

标签:25,Java,子类,dog,多态,Dog,抽象类,父类,方法
来源: https://www.cnblogs.com/fulfill/p/16004055.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有