/**
多态 :
一个对象的多种父类的形态.
本态 :
一个对象的本类类型的形态.
本态引用 :
一个子类对象赋值于本类类型的引用变量.
多态引用 :
一个子类对象赋值于父类类型的引用变量.
*/
class Person {
private String name;
private int age;
private String gender;
public Person() {
//System.out.println("Person()...");
}
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
//System.out.println("Person(3)...");
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getGender() {
return gender;
}
public String say() {
return "姓名:" + this.name + ",年龄:" + this.age + ",性别:" + this.gender;
}
public void sleep() {
System.out.println("在睡觉");
}
public void sayHello() { // 虚拟方法
System.out.println("打个招呼 .... ");
}
}
/**
每个类的构造器都必须先执行父类构造器
1) 类的构造器的第一行总是super(...), 直接调用父类构造器
2) 类的构造器的第一行不是super(...)就是this(...), 间接调用父类构造器
*/
class Chinese extends Person {
private String shuxiang;
public Chinese() {
//super(); //不可以和this(...)共存
this("某人", 10, "未知", "狗"); // 对父类构造器的间接调用
//System.out.println("Chinese()...");
}
public Chinese(String name, int age, String gender, String shuxiang) {
super(name, age, gender);
this.shuxiang = shuxiang;
//System.out.println("Chinese(4)...");
}
public void setShuxiang(String shuxiang) {
this.shuxiang = shuxiang;
}
public String getShuxiang() {
return shuxiang;
}
public void spring() {
System.out.println("欢欢喜喜过大年");
}
@Override
public String say() {
return super.say() + ",属相:" + shuxiang;
}
@Override
public void sayHello() {
System.out.println("吃的啥呀?");
}
}
class American extends Person {
private boolean hasGun;
public American() {
}
public American(String name, int age, String gender, boolean hasGun) {
super(name, age, gender);
this.hasGun = hasGun;
}
public void setHasGun(boolean hasGun) {
this.hasGun = hasGun;
}
public boolean isHasGun() {
return hasGun;
}
public void christmas() {
System.out.println("过圣诞节...");
}
@Override
public void sayHello() {
System.out.println("How are you?");
}
@Override
public String say() {
return super.say() + "," + (hasGun ? "有枪" : "没枪");
}
}
class Peking extends Chinese {
}
class PersonTest4 {
public static void test(Person p) { // 多态参数, 实参可以接收一个家族的任意对象
System.out.println(p.say());
p.sayHello();
if (p instanceof Chinese) { // 询问p指向的对象是不是Chinese类型的一个对象
((Chinese)p).spring(); // 多态副作用 , 造型
} else if (p instanceof American) {
American a = (American)p;
a.christmas();
} else {
System.out.println("普通人一枚");
}
}
public static void main(String[] args) {
Person[] arr = new Person[5]; // 多态数组, 元素可以兼容本类及其子类对象
arr[0] = new American("Jack", 20, "male", true);
arr[1] = new Chinese("张三", 30, "男", "狗");
arr[2] = new Person("某人", 10, "未知");
arr[3] = new Chinese("李四", 40, "女", "龙");
arr[4] = new American("Mary", 25, "female", false);
for (int i = 0; i < arr.length; i++) {
test(arr[i]);
}
}
}
class PersonTest3 {
public static void main(String[] args) {
Chinese ch = new Chinese("张三", 30, "男", "狗");
Person p1 = ch; // 多态引用
//p1.spring(); // 编译器会检查p1所属的类型中是否有此方法
p1 = new American("Rose", 20, "female", false);
p1.sayHello(); // 虚方法调用
}
}
class PersonTest2 {
public static void main(String[] args) {
//Chinese ch = new Chinese(); // 本态引用
Person person = new Chinese(); // 多态引用
//person.spring(); // 多态副作用 : 子类特有成员会被隐藏
person.sayHello(); // 只能调用父类中定义的成员,
// 虚方法调用, 在多态环境下的覆盖方法的调用
// 1) 编译时检查父类类型
// 2) 在运行时,执行的是子类中的方法(动态绑定)
person = new American("Jack", 30, "male", true);
person.sayHello(); //执行子类的方法
person = new Person();
person.sayHello(); // 不是虚方法调用
// 使用多态创建NotePad,PC
// 打印输出对象的getDetails方法.
}
}
class PersonTest {
public static void main(String[] args) {
//Chinese ch = new Chinese("张三", 30, "男", "猪");
Chinese ch = new Chinese();
System.out.println(ch.say());
Chinese ch2 = new Chinese("张三", 30, "男", "猪");
System.out.println(ch2.say());
}
}