多态
多态:子类对象被赋值给父类引用(父类引用指向子类对象)
本态:子类对象被赋值给本类引用
Java程序执行过程有编译时类型,运行时类型
编译时类型,编译器在编译时只关注引用类型
运行时类型,此时程序怎么执行主要看对象
多态形成:
子类重写父类的某一方法,子类对象创建好后,将地址赋给父类引用,因为父类中有子类重写的方法,这样可以欺骗编译器通过编译,然后在执行的时候主要是看对象,此时运行的是子类重写的方法。(虚方法调用)
虚方法调用:(多态环境下覆盖方法的调用)
1.编译时检查父类(引用变量所属的类)
2.在运行时,执行的是子类中的方法(动态绑定)(对象所属的类)
成员方法:有虚方法调用
成员变量:只看引用变量所属类(不具有多态性)
多态参数:实参可以接受一个家族的任意对象
1.将子类对象赋值给父类引用,这样将父类引用作为参数,就可以传入继承体系中的所有子类对象,在方法中在对子类对象所属进行判断(a instanceof A —>对象a是不是类A的对象),进行造型,(对象还原)然后调用重写的方法,可以形成多态(不同的子类对象得到不同的结果)(实参可以接收一个家族的任意对象)
多态数组:元素可以兼容本类及其子类对象
2.创建父类类型数组:可以保存本类和所有子类的对象(多态数组)
子类对象创建—-内存中执行过程(谁调用谁就是this)
子类对象内存中的创建过程:
1.检查永久区中有没有继承体系中的所有类的类模板(方法保存在类模板中,方法只有一份)
2.使用类加载器加载所有涉及的类到永久区中
3.根据类模板中的属性定义,从最父类—>最子类搜索,在GC区中开辟一块合适的内存空间
4.对该内存区域清0
5.查看属性有没有显式赋值,若有进行显式赋值,没有不执行
6.执行构造器初始化,从最父类—>最子类执行。
7.将对象的首地址赋值给子类对象的引用变量
多态代码:
public class Computer {
private double cpu;
private int memory;
private int disk;
private int price;
public Computer() {
}
public Computer(double cpu, int memory, int disk, int price) {
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
this.price = price;
}
public void setCpu(double cpu) {
this.cpu = cpu;
}
public void setMemory(int memory) {
this.memory = memory;
}
public void setDisk(int disk) {
this.disk = disk;
}
public double getCpu() {
return cpu;
}
public int getMemory() {
return memory;
}
public int getDisk() {
return disk;
}
public void setPrice(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
public String getDetails() {
return "cpu:" + cpu + ",内存:" + memory + ",磁盘:" + disk + ",价格:" + price;
}
}
public class NotePad extends Computer {
private int satellite; //卫星
public NotePad() {
}
//double cpu, int memory, int disk int price
public NotePad(double cpu, int memory, int disk, int price, int satellite) {
super(cpu, memory, disk, price);
this.satellite = satellite;
}
public void setSatellite(int satellite) {
this.satellite = satellite;
}
public int getSatellite() {
return satellite;
}
public void navigating() {
System.out.println("导航");
}
@Override
public String getDetails() {
// return "cpu:" + getCpu() + "内存:" + getMemory() + "磁盘:" + getDisk() + "卫星:" + satellite;
return super.getDetails() + ",卫星:" + satellite;
}
}
public class PC extends Computer {
private String keyboard;
public PC() {
}
//double cpu, int memory, int disk int price
public PC(double cpu, int memory, int disk, int price, String keyboard) {
super(cpu, memory, disk, price);
this.keyboard = keyboard;
}
public void setKeyboard(String keyboard) {
this.keyboard = keyboard;
}
public String getKeyboard() {
return keyboard;
}
public void code() {
System.out.println("编码");
}
@Override
public String getDetails() {
return super.getDetails() + ",机械:" + keyboard;
}
}
public class Test1 {
//将父类引用作为形参在listPrice方法中,可以接受本类及其子类的任意对象,然后在方法内部对实际对象进行判断,造型,调用方法,形成多态
public static void listPrice(Computer computer) {
//System.out.println(computer.getPrice());
if(computer instanceof PC) {
((PC)computer).code();
} else if(computer instanceof NotePad) {
((NotePad)computer).navigating();
} else {
System.out.println("Computer");
}
}
public static void main(String[] args) {
/*
//double cpu, int memory, int disk, String keyboard
Computer computer = new PC(3.4 , 16, 10000, "机械");
System.out.println(computer.getDetails());
//double cpu, int memory, int disk, int satellite
Computer computer2 = new NotePad(1.2 , 4, 64, 8);
System.out.println(computer2.getDetails());
*/
//double cpu, int memory, int disk, int price
//定义一个父类数组其中可以保存本类及其子类对象
Computer[] computers = new Computer[6];
computers[0] = new PC(3.4 , 16, 10000,12233, "机械");
computers[1] = new PC(5.5 , 24, 1000, 13260, "机械");
computers[2] = new NotePad(1.2 , 4, 64, 6888, 8);
computers[3] = new NotePad(2.5 , 8, 10000, 5688, 5);
computers[4] = new Computer(5.6 , 10, 8888, 10000);
computers[5] = new Computer(2.8 , 16, 30000,100000);
//根据价格进行排序
for(int i = 0; i < computers.length; i++) {
for(int j = 0; j < computers.length - 1 - i; j++) {
if(computers[j].getPrice() > computers[j + 1].getPrice()) {
Computer temp = computers[j];
computers[j] = computers[j + 1];
computers[j + 1] = temp;
}
}
}
//遍历输出排好序的数组
for(int i = 0; i < computers.length; i++) {
System.out.println(computers[i].getDetails());
}
System.out.println("---------------------------------------");
//打印价格
for(int i = 0; i < computers.length; i++) {
listPrice(computers[i]);
}
System.out.println("----------------------------------------");
PC pc = new PC(3.4 , 16, 10000,12233, "机械");
listPrice(pc);
NotePad notepad = new NotePad(2.5 , 8, 10000, 5688, 5);
listPrice(notepad);
System.out.println("----------------------------------------");
for(int i = 0; i < computers.length; i++) {
listPrice(computers[i]);
}
}
}