Java
基础知识
01概述
02变量
03运算符
04程序控制语句
05数组
06面向对象编程
07代码练习
08重载
09作用域
10构造方法&构造器
11this
12包
13修饰符
14封装
15继承
16super
17覆盖&重写
18多态
19零钱通项目
20类变量&类方法
21抽象类
22接口
23内部类
24枚举
25泛型
26常用API
27lambda表达式
28正则表达式
29异常
30File&IO流
31日志技术
32多线程
33网络编程
-
+
首页
18多态
## 案例 编写一个程序,Master类中有一个feed(喂食)的方法,可以完成主人对动物喂食物的操作。  **代码** food类 ```java package com.xbxaq.poly_; public class Food { private String name; public Food(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` fish类 ```java package com.xbxaq.poly_; public class Fish extends Food{ public Fish(String name){ super(name); } } ``` bone类 ```java package com.xbxaq.poly_; public class Bone extends Fish{ public Bone(String name){ super(name); } } ``` animal类 ```java package com.xbxaq.poly_; public class Animal { private String name; public Animal(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` dog类 ```java package com.xbxaq.poly_; public class Dog extends Animal{ public Dog(String name) { super(name); } } ``` cat类 ```java package com.xbxaq.poly_; public class Cat extends Animal{ public Cat(String name) { super(name); } } ``` master类 ```java package com.xbxaq.poly_; public class Master { private String name; public Master(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 完成主人对小狗的喂食效果 public void feed(Dog dog, Bone bone){ System.out.println("主人 " + name + " 给" + dog.getName() + "喂 " + bone.getName()); } } ``` poly类 ```java package com.xbxaq.poly_; public class Poly01 { public static void main(String[] args) { Master tom = new Master("tom"); Dog dog = new Dog("小白"); Bone bone = new Bone("大白骨"); tom.feed(dog, bone); } } ``` 运行结果  ## 基本概述 - 方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承基础之上的。 ## 多态的具体体现 1、方法的多态(重载与重写) 2、对象的多态 ```txt 一个对象的编译类型和运行类型可以不一致。 编译类型在定义对象时,就确定了,不能改变 允许类型是可以变化的 编译类型看定义时 =号的左边,运行类型看 =号的右边 ``` ## 多态的细节 1、多态的前提是:两个对象(类)存在继承关系 2、多态的向上转型,本质为父类的引用指向了子类的对象 ```txt 语法:父类类型 引用名 = new 子类类型() 特点:编译类型看右边,运行类型看左边 可以调用父类的所有成员(需遵守访问权限),不能调用子类的特有成员。 ``` 3、多态的向下转型 ```txt 语法:子类类型 引用名 = (子类类型) 父类引用; 只能强转父类的引用,不能强转父类的对象 要求父类的引用必须指向的是当前目标类型的对象 当向下转型后可以调用子类类型中所有的成员 ``` 4、属性没有重写之说,属性的值看编译类型 animal类  cat类  Detail类  结果  ## 动态绑定机制 - 当调用对象方法时,该**方法会和对象的内存地址[也就是运行类型]进行绑定** - 当调用对象属性时,没有动态绑定机制,哪里声明哪里使用 > 示例代码-1 ```java public class BangDing{ public static void main(String args[]){ A a = new B(); System.out.println(a.sum()); System.out.println(a.sum1()); } } class A{ public int i = 10; public int sum(){ return getl() + 10; } public int sum1(){ return i + 10; } public int getl(){ return i; } } class B extends A { public int i = 20; public int sum(){ return i + 20; } public int getl(){ return i; } public int sum1(){ return i + 10; } } ```  > 代码示例-2 ```java public class BangDing{ public static void main(String[] args){ A a = new B(); System.out.println(a.sum()); System.out.println(a.sum1()); } } class A{ public int i = 10; public int sum(){ return getl() + 10; } public int sum1(){ return i + 10; } public int getl(){ return i; } } class B extends A { public int i = 20; // public int sum(){ // return i + 20; // } public int getl(){ return i; } public int sum1(){ return i + 10; } } ```  > 代码示例-3 ```java public class BangDing{ public static void main(String[] args){ A a = new B(); System.out.println(a.sum()); System.out.println(a.sum1()); } } class A{ public int i = 10; public int sum(){ return getl() + 10; } public int sum1(){ return i + 10; } public int getl(){ return i; } } class B extends A { public int i = 20; // public int sum(){ // return i + 20; // } public int getl(){ return i; } // public int sum1(){ // return i + 10; // } } ```  ## 多态数组 - 多态数组:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型 > 应用实例-1 现有一继承结构,要求创建一个person对象、两个student对象和两个teacher对象,统一放在数组中,并调用每个对象的say方法。 <img src="https://oss.maolin101.com/202402281823091.png-101.webp" alt="image-20240228172630018" style="zoom:80%;" /> plaoarray类 ```java public class PloyArray{ public static void main(String[] args){ Person[] person = new Person[5]; person[0] = new Person("zhangsan",30); person[1] = new Student("wangwu",18,74.0); person[2] = new Student("wangpeng",17,89.5); person[3] = new Teacher("zhangxiwang",32,15000); person[4] = new Teacher("luoping",32,20000); //遍历多态数组调用say方法 for (int i = 0; i < person.length; i++) { System.out.println(person[i].say()); //动态绑定机制 } } } ``` person类 ```java public class Person{ private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name){ this.name = name; } public int getAge(){ return age; } public void setAge(int age){ this.age = age; } public String say(){ return name + "\t" + age; } } ``` teacher类 ``` public class Teacher extends Person{ private double salary; public Teacher(String name, int age,double salary){ super(name,age); this.salary = salary; } public double getSalary(){ return salary; } public void setSalary(){ this.salary = salary; } @Override public String say() { return super.say() + " salary=" + salary; } } ``` student类 ``` public class Student extends Person{ private double score; public Student(String name, int age, double score){ super(name,age); this.score = score; } public double getScore(){ return score; } public void setScore(double score){ this.score = score; } //重写say方法 public String say(){ return super.say() + " score=" + score; } } ``` 运行效果  > 应用实例-2 如何调用子类特有的方法,例如:teacher类有一个teach方法,student类有一个study方法,该如何调用呢 plaoarray类 ```java public class PloyArray{ public static void main(String[] args){ Person[] person = new Person[5]; person[0] = new Person("zhangsan",30); person[1] = new Student("wangwu",18,74.0); person[2] = new Student("wangpeng",17,89.5); person[3] = new Teacher("zhangxiwang",32,15000); person[4] = new Teacher("luoping",32,20000); //遍历多态数组调用say方法 for (int i = 0; i < person.length; i++) { System.out.println(person[i].say()); //动态绑定机制 if (person[i] instanceof Teacher){ ((Teacher)person[i]).teach(); } if (person[i] instanceof Student){ ((Student)person[i]).study(); } } } } ``` person类 ```java public class Person{ private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name){ this.name = name; } public int getAge(){ return age; } public void setAge(int age){ this.age = age; } public String say(){ return name + "\t" + age; } } ``` teacher类 ``` public class Teacher extends Person{ private double salary; public Teacher(String name, int age,double salary){ super(name,age); this.salary = salary; } public double getSalary(){ return salary; } public void setSalary(){ this.salary = salary; } @Override public String say() { return super.say() + " salary=" + salary; } public void teach(){ System.out.println("教师:" + getName()); } } ``` student类 ``` public class Student extends Person{ private double score; public Student(String name, int age, double score){ super(name,age); this.score = score; } public double getScore(){ return score; } public void setScore(double score){ this.score = score; } //重写say方法 public String say(){ return super.say() + " score=" + score; } public void study(){ System.out.println("学生" + getName()); } } ``` 运行效果  ## 多态参数 - 多态参数:方法定的形参类型为父类类型,实参类型允许为子类类型 > 实例 需求:定义员工类Employee其中包含姓名name、月工资[private]以及计算年工资的getAnnual方法,普通员工和经理继承了员工,经理类多了奖金bonus属性和管理manage方法,普通员工类多了work方法,普通员工和经理类要求分别重写getAnnual方法 测试类中添加一个方法showEmpAnnual(employee e),实现获取任何员工对象的工资,并在main方法中调用该对象 测试类中添加一个方法testWork,如果是普通员工,则调用Work方法,如果是经理则调用manage方法 Employee类 ```java public class Employee{ private String name; private Double salary; // 年工资 public double getAnnual(){ return 12 * salary; } public Employee(String name, Double salary){ this.name = name; this.salary = salary; } public String getName(){ return name; } public Double getSalary(){ return salary; } public void setName(String name){ this.name = name; } public void setSalary(Double salary){ this.salary = salary; } } ``` worker类 ```java public class Worker extends Employee{ public Worker(String name,double salary){ super(name,salary); } public void work(){ System.out.println("员工" + getName() + "正在工作"); } public double getAnnual(){ return super.getAnnual(); } } ``` manager类 ```java public class Manager extends Employee{ private double bonus; public void manage(){ System.out.println("经理" + getName() + "正在管理"); } public Manager(String name,double salary,double bonus){ super(name,salary); this.bonus = bonus; } public double getBonus(){ return bonus; } public void setBonus(double bonus){ this.bonus = bonus; } public double getAnnual(){ return super.getAnnual() + bonus; } } ``` PloyParameter类 ```java public class PloyParameter{ public static void main(String[] args){ Worker tom = new Worker("tom",10.0); Manager zhangsan = new Manager("zhangsan",7000,10000); PloyParameter ployParameter = new PloyParameter(); ployParameter.showEmpAnnual(tom); ployParameter.showEmpAnnual(zhangsan); ployParameter.testWork(tom); ployParameter.testWork(zhangsan); } //添加一个方法showEmpAnnual(employee) public void showEmpAnnual(Employee e){ System.out.println(e.getAnnual()); } // 添加一个方法testWork,如果是普通员工,则调用testWork方法,如果是经理则调用manage方法 public void testWork(Employee e){ if (e instanceof Worker){ ((Worker) e).work(); }else if(e instanceof Manager){ ((Manager) e).manage(); } } } ``` 运行效果  ## 细节讨论 **属性看编译类型,方法看运行类型** > 属性没有重写之说,属性的值看编译类型 代码 ```java public class a1{ public static void main(String[] args){ Base base = new Sub(); System.out.println(base.count); Sub sub = new Sub(); System.out.println(sub.count); } } class Base{ int count = 10; } class Sub extends Base{ int count = 20; } ```  > instanceOf比较操作符,用于判断对象的运行类型是否为xx类型或者xx类型的子类型 ```java public class a1{ public static void main(String[] args){ Sub sub = new Sub(); System.out.println(sub instanceof Sub); System.out.println(sub instanceof Base); } } class Base{ } class Sub extends Base{ } ``` 
毛林
2025年9月7日 12:13
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码