标签:类型 oid 需求 扩展性 test 类继承 关联 this 动态
1) 需要具有子父类的继承关系(类与接口实现关系)
2) 子类重写从父类继承来的方法
3) 父类的引用指向子类的对象
举例 :
class Person{}
class Doctor extends Person{}
class Teacher extends Person{}
多态表达式:
Person p; // 父类引用
new Doctor(); // 子类对象
new Teacher() ;// 子类对象
Person p = new Doctor(); // 人类p的表现形式是医生
Person p1 = new Teacher(); // 人类p1的表现形式是教师
以上表达式能体现出人类的多种表现形式,这就是多态的概念
代码
public class Person { public void eat() { System.out.println("人都需要吃饭"); } }
public class Doctor extends Person { @Override public void eat() { System.out.println("医生吃的比较清淡"); } }
public class Teacher extends Person { @Override public void eat() { System.out.println("教师今天想吃凉皮"); } }
public class TestDuoTai { public static void main(String[] args) { // 多态表达式 Person p = new Doctor(); p.eat();// 医生吃的比较清淡 Person p1 = new Teacher(); p1.eat();// 教师今天想吃凉皮 } }
使用多态表达式调用成员方法
1) 编译看左 : 编译代码时, 如果多态表达式调用的这个方法, 在 等号的左边的类型中不存在(没定义), 那么直接报错,无法编译通过. 如果等号左边的类型中存在调用的方法,编译成功
2) 运行看右 : 使用多态的表达式调用方法,运行时动态绑定等号右边的类型中的方法实现, 实际运行的就是等号右边子类中的重写方法
代码
public class Person { public void eat() { System.out.println("人都需要吃饭"); } }
public class Doctor extends Person { @Override public void eat() { System.out.println("医生吃的比较清淡"); } // 医生特有的救人功能 public void savePerson() { System.out.println("医生可以治病救人"); } }
public class Teacher extends Person { @Override public void eat() { System.out.println("教师今天想吃凉皮"); } // 老师特有功能授课 public void teach() { System.out.println("老师可以授课"); } }
public class TestDuoTai { public static void main(String[] args) { // 多态表达式 // 1. 编译看左,运行看右 Person p = new Doctor(); // eat方法在等号左边的类型Person中存在(定义) p.eat();//医生吃的比较清淡 // savePerson方法在等号左边的类型Person中不存在,因此报出编译错误 // p.savePerson(); //The method savePerson() is undefined for the type Person Person p1 = new Teacher(); p1.eat();//教师今天想吃凉皮 // p1.teach(); } }
Person p = new Doctor();
向上转型的实质 : 对象引用p使用范围缩小, 只能使用子父类中的共有方法
2.多态向下转型 :
目的 : 为了解决多态表达式中,无法使用子类特有方法的局限性, 想要使用子类中的特有方法功能
多态向下转型公式: 将指向子类对象的父类引用, 恢复成子类类型
举例 : Doctor d = (Doctor)p;
向下转型实质 : 对象引用p使用范围变大, 可以使用子类中的内容
需求 : 现有一农场,需要设计出一个方法, 功能是提供不同的动物类型,能输出每一种动物需要投喂的食物, 请根据多态设计出这个方法功能
举例 : 给该方法传递猫类型数据 : 提示, 喂鱼 ; 给该方法传递狗类型数据 : 提示 , 吃骨头; 给该方法传递羊类型数据 : 提示 , 喂草 .... 每一种动物都能得到对应的喂食结果
代码
public class Animal { // 将所有动物都需要喂食功能 : eat public void eat() { System.out.println("所有动物都需要喂食"); } }
public class Cat extends Animal { @Override public void eat() { System.out.println("猫喂鱼"); } }
public class Dog extends Animal { @Override public void eat() { System.out.println("狗喂骨头"); } }
public class Farmer { // 方法功能 : 将每一种动物喂食结果显示出来 public void wei(Animal a) {// Animal a = new Sheep(); a.eat(); } public void useI(int i) {// int i = 10; System.out.println(i); } }
将事物的共性向上抽取,抽取到父类中, 但是当共性抽取到一定程度时, 父类中不知道如何实现共性内容才能让每一个子类都满足实际需求, 于是父类中将共性方法只做方法的声明,而没有方法的实现,这样的方法称为抽象方法
2.抽象方法的定义:
需要使用关键字 : abstract
修饰符 abstract 返回值类型 方法名(参数列表);
3.抽象类的定义:
修饰符 abstract class 类名{
// 抽象方法只能存在于抽象类中
}
4.抽象方法存在是为了为子类限定一些需要实现的规则
代码
public abstract class Animal { // 抽象方法 // The abstract method eat in type Animal can only be defined by an abstract class // 抽象方法只能定义在抽象类中 public abstract void eat(); }
public abstract class Animal{
public abstract void eat();
}
2.抽象类和抽象方法之间的关系:
1) 抽象方法必须定义在抽象类中
2) 抽象类中可以没有抽象方法
3.抽象类的实例化(实例化 : new对象)
1) 抽象类不能实例化对象(不能new对象)
因为抽象类中可以含有抽象方法, 而抽象方法因为没有方法体,不能运行的,因此抽象类不能new对象
2) 抽象类等着当父类,等着被子类继承, 需要一个子类继承这个抽象类, 让子类将抽象父类中的所有抽象方法全部重写, 通过创建子类对象,实现方法的调用
4.抽象类的子类前途:
1) 子类将抽象父类中的所有抽象方法全部重写, 子类可以正常创建对象使用
2) 子类没有将抽象父类中的所有抽象方法全部重写, 子类仍然还是一个抽象类
抽象类中的成员 : 先把抽象类当做一个普通类, 在此基础上可以定义抽象方法
1.可以定义成员变量
2.可以定义构造方法
一个类型是否可以定义构造方法,与这个类型能否创建对象无关, 与类型中是否能定义成员变量有关. 只要一个类型中可以定义成员变量,那么这个类型就可以定义构造方法
3.可以定义非抽象方法
为了给子类直接继承使用
4.可以定义抽象方法
为了给子类限定需要实现的规则
抽象的练习 :
每个员工Employee都具有属性(姓名,工号,工资),行为 : 工作
程序员类: 属性(姓名,工号,工资,奖金), 行为 : 工作(软件开发)
测试工程师类 : 属性(姓名,工号,工资), 行为 : 工作(软件测试)
项目经理类 : 属性(姓名,工号,工资,奖金),行为 : 工作(控制工作进度)
请设计出合适的类关系,并测试
代码
public abstract class Employee { // 姓名,工号,工资 private String name; String id; double salary; public String getName() { return name; } public void setName(String name) { this.name = name; } public abstract void work(); }
public class Employee_程序开发 extends Employee{ private double jiangjin; public Employee_程序开发(String name , String id, double salary, double jiangjin) { super(); this.jiangjin = jiangjin; this.id = id; setName(name); this.salary = salary; } public Employee_程序开发() { super(); } public double getJiangjin() { return jiangjin; } public void setJiangjin(double jiangjin) { this.jiangjin = jiangjin; } @Override public void work() { System.out.println(getName() +"---"+ id +"---"+ salary + "---"+jiangjin+"程序员做开发"); } }
public class Employee_测试工程师 extends Employee{ @Override public void work() { System.out.println("测试工作"); } }
public class TestEmployee { public static void main(String[] args) { Employee_程序开发 e1 = new Employee_程序开发("小张","007",15678.99,3200); e1.work(); Employee_测试工程师 e2 = new Employee_测试工程师(); e2.work(); } }
因为接口中全部都是抽象方法, 抽象方法只方法的声明, 方法功能的声明和方法的实现分离, 让类型与类型之间的耦合度(关联度)降低
使用关键字 interface : 用于定义出接口类型
修饰符 interface 接口名{
// 抽象方法(随着JDK版本的推进, 接口中不仅仅只有抽象方法,目前学习中,以抽象方法为学习重点,JDK8新特性,讲解接口中的其他方法定义)
}
代码
public interface MyInter { // 定义抽象方法 public abstract void fun(); public abstract boolean equalDouble(double d, double d1); }
接口需要一个实现类, 将接口中的所有抽象方法重写,通过创建实现类对象,调用重写方法
3.类与接口之间的关系:实现关系 implements (与类和类之间的继承extends关系非常相似)
举例 : interface MyInter{}
class MyInterImpl implements MyInter{
// 将接口中的抽象方法全部重写;
}
4.接口实现类的前途:
1) 如果实现类将接口中的所有抽象方法全部重写,那么这个实现类可以正常使用
2) 如果实现类没有将接口中的所有抽象方法全部重写, 那么这个实现类是抽象类, 抽象类不能实例化对象
标签:类型 oid 需求 扩展性 test 类继承 关联 this 动态
原文地址:https://www.cnblogs.com/a595452248/p/13416318.html