Father f1 = new Son(); // 这就叫 upcasting (向上转型)
// 现在 f1 引用指向一个Son对象
Son s1 = (Son)f1; // 这就叫 downcasting (向下转型)
// 现在f1 还是指向 Son对象
Father f2 = new Father();
Son s2 = (Son)f2; // 出错,子类引用不能指向父类对象
f1 指向一个子类对象,Father f1 = new Son(); 子类 s1 引用可以指向子类对象。
而 f2 被传给了一个 Father 对象,Father f2 = new Father(); 子类 s2 引用不能指向父类对象。
总结:
1、父类引用指向子类对象,而子类引用不能指向父类对象。
2、把子类对象直接赋给父类引用叫 upcasting 向上转型,向上转型不用强制转换。
3、把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转换。
一. 向上转型
1. 向上转型中的方法调用
1:发生向上转型后,子类独有的方法是调用不了的
2:在发生向上转型后,调用的方法和 new 的对象有关,调用的属性和类型有关(static除外)
3:向上转型,一个类既可以转型为父类,也可以转型为祖先类!
package com.zth;
class Animal {
String name = "Animal";
public void eat() {
System.out.println("animal eating...");
}
}
class Bird extends Animal {
String name = "brid";
public void eat() {
System.out.println("bird eating...");
}
public void fly() {
System.out.println("bird flying...");
}
}
public class Test{
public static void main(String[] args) {
Animal b = new Bird();
System.out.println(b.name);
b.eat();
// b.fly(); 报错
}
}
执行结果:
Animal
bird eating...
2、向上转型的好处
以父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。
package com.zth;
class Human{
public void sleep() {
System.out.println("Human sleep...");
}
}
class Male extends Human{
@Override
public void sleep() {
System.out.println("Male sleep...");
}
}
class Female extends Human{
@Override
public void sleep() {
System.out.println("Female sleep...");
}
}
public class Test{
public static void dosleep(Human h) {
h.sleep();
}
public static void main(String[] args) {
dosleep(new Male());
dosleep(new Female());
}
}
执行结果:
Male sleep...
Female sleep...
二. 向下转型
与向上转型相反,即是把父类对象转为子类对象。
package com.zth;
class Animal {
String name = "Animal";
public void eat() {
System.out.println("animal eating...");
}
}
class Bird extends Animal {
String name = "bird";
public void eat() {
System.out.println("bird eating...");
}
public void fly() {
System.out.println("bird flying...");
}
}
public class Test{
public static void main(String[] args) {
Animal b = new Bird(); // 向上转型
System.out.println(b.name); // Animal
b.eat(); // bird eating...
//b.fly(); error
Bird b1 = (Bird)b; // 向下转型
System.out.println(b1.name); // bird
b1.eat(); // bird eating...
b1.fly(); // bird flying...
Animal bb = new Animal();
//Bird b2 = (Bird)bb; //不安全的向下转型,编译无错但会运行会出错
if(bb instanceof Bird) {
Bird b2 = (Bird)bb;
System.out.println(b2.name);
b2.eat();
}
}
}
三. instanceof 关键字
instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。
instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
package com.zth;
class Person{
String name;
int age;
public Person() {
}
public Person( String name, int age) {
this.name = name;
this.age = age;
}
public boolean equals(Object obj) {
if(obj instanceof Person) {
Person p1 = (Person) obj;
return this.name.equals(p1.name) && this.age == p1.age;
}else {
return false;
}
}
}
class Teacher extends Person{
public Teacher(String name,int age) {
this.name = name;
this.age = age;
}
}
public class Test1 {
public static void main(String[] args) {
Person p = new Person("zth",18);
Teacher p1 = new Teacher("zth",18);
System.out.println(p.equals(p1)); // true
System.out.println(p.equals("zth")); // false
}
}