多态
package Demo2;
/**多态
- 老张开车去东北 使用面向对象的思想设计程序
- 第一步:抽象两个类
-
老李开飞机去上上海
-
person car Address="东北”
- 已经通过面向对象设计完成了
- 老李开卡车去东北
- 老孙开着火车去东北 创建火车 Train
- 问题:
-
1.有重复的脚本 继承和重写 抽取共性 复用
-
2.更换交通工具的时候需要修改person驾驶方法的参数drive(Car car) 不满足开闭原则
-
解决:把形参修改为父类,实参是具体的子类 public void drive(TranSport tran )
- 多态
*什么叫多态:
*1.继承是多态的前提
*2.父类引用指向子类对象
*
*
*
*
*多态:
- 1.继承和重写 父类的引用 new的子类对象
- 2.父类引用指向子类对象 TranSport tran=new Train();
*/
public class Car extends TranSport {
//车跑的行为是复杂的
@Override
public void run(String name) {
// TODO 自动生成的方法存根
//轿车跑的行为
//super.run(name);
System.out.println(name+"开着小轿车去"+"东北");
}
/**
*
* 成员变量
* 成员方法
*/
}
```
package Demo2;
/**
*
*
*
* @author lenovo
*
*/
public class Person {
/**
* 成员变量
* 成员方法
*/
String name;
private int age;//封装
//类里边的成员变量设置成私有的保证在设置值的时候进行限制
public int getAge() {
return age;
}
//保护age 在设置age值的时候给一个限制
public void setAge(int age) {
if(age>120||age<0) {
System.out.println("年龄不符合规则");
this.age=30;//凡是不符合年龄的 一律默认30岁
}else {
this.age = age;
}
}
public Person(String name, int age) {
this.name = name;
this.setAge(age);//将age作为参数传给setAge进行条件判断最终达到限制的目的
}
public void eat() {
System.out.println("吃饭");
}
public void play( String gameName) {
System.out.println("玩"+gameName);
}
//老张开车去东北
// public void drive(Car car ) {
// car.run(name);
// }
public void drive(TranSport tran ) {
//truck.run(name);
tran.run(name);
}
}
package Demo2;
public class Test {
public static void main01(String[]args) {
// Person person=new Person("老张",1900);
// System.out.println(person.getAge());
// // Car car=new Car();
// // person.drive(car);
// System.out.println("===================");
// Person p=new Person("老李",18);
// Truck truck=new Truck();
// Car car=new Car();
//
// Train train=new Train();
// // public void drive(TranSport tran )
// //把驾驶里边的方法换成了交通工具类
// p.drive(car);
}
public static void main(String[]args) {
// Car car=new Car();
// car.run("老孙");
// Truck truck=new Truck();
// truck.run("老孙");
// //以上都不是多态
// TranSport tran=new Car();
// tran.run("老孙");
// TranSport tran1=new Car();
// tran1.run("老孙");
//父类引用指向子类
//1.存在继承和重写 多态的前提
//2.父类引用指向子类对象
// TranSport transport=new TranSport();
// transport.run("老孙");
TranSport tran=new Train();
tran.run("老孙");
//目前实现多态的方式有两种:1.普通类做父类 2.用抽象类做父类
//什么时候用普通类/什么时候用抽象类呢?
//1.当需要父类做一些东西的时候 用普通类做父类
//2.当不需要父类做任何事情的时候用抽象类
//疑问:
//1.怎么判断调用谁的问题
//1.成员变量 1.直接调用 =左边是谁就调用谁 没有往上找
// 间接调用:2.类内部方法调用,方法属于谁就优先调用谁,没有往上找 所以有了多态
//成员方法 new的是谁调用谁 没有往上找
// TranSport tran3= new Car();
//运行的时候 在堆上开辟内存 存储car的方法地址
//如果检测到重写把父类的地址修改为子类重写后的地址
// tran3.run("老孙");
//TranSport tran1 new TranSport()
//成员变量的调用看等号左边是谁
//成员变量的调用看等号右边是谁
//2.疑问2:
/**
*父类还能创建子类对象
* TranSport tranSport=new TranSport()(保证父类不是抽象类); 父类指向父类
* 解释:父类指向父类 特点:1.调用父类的内容 2.抽象类不能直接new 自己
* Train train= new Train(); 子类指向子类
* 解释:子类指向子类 特点:1.调用子类的内容 没有往上找
* TranSport transport2=new Car(); 父类指向子类(向上转型)long 1=123;
* 解释:父类指向子类 特点:1.成员变量调用父类的 成员方法看new的是谁(多态的必要条件)
* 注意事项:抽象类也可以直接new 子类
* Car car=(Car)(new TranSport()); 子类指向父类
* 一般不会将父类转换成一个子类
* TranSport transport2=new Car();
* Car car=(Car)(transport)//向下转型
* 想访问子类里边的成员变量 子类的成员变量对于父类的成员变量
* 解释:子类指向父类 特点:把原本子类类型转回来
* 存在的问题:可能会报错 编译看不出来 运行会报错
*
* TranSport transport2=new Train();
* 无法将火车转换成一个小轿车 (不同子类无法转换成同一个子类)
* Car car=(Car)(transport)//向下转型
* Car car=(Car)(new TranSport()); 不可以这样装
* 无法将一个父类转换成一个子类
*向下转型是有判断机制的
*if(transport2 instanceof Car)
*transport2 instanceof Car 返回一个布尔值
*
*{
* instanceof(实例是来自)判断是否是对应的类型
* Car car=(Car)(transport2)
* System.out.println("没进来");
* }
*疑问3.多态在选择父类的时候 选择抽象类还是普通类
* 如果需要父类做东西 普通类
* 如果不需要父类做东西 抽象类(可以包含普通方法)
* 疑问4.
*
*/
}
}
package Demo2;
public class Train extends TranSport {
@Override
public void run(String name) {
// TODO 自动生成的方法存根
//super.run(name);
System.out.println(name+"开着火车去"+"东北");
}
}
package Demo2;
public abstract class TranSport {
public abstract void run(String name); //{
// TODO 自动生成的方法存根
//轿车跑的行为
//抽取所有交通工具的共性
//System.out.println(name+"打开导航");
//}
}
package Demo2;
public class Truck extends TranSport {
@Override
public void run(String name) {
//super.run(name);
// TODO 自动生成的方法存根
//卡车跑的行为
System.out.println(name+"开着大卡车去"+"东北");
}
}