【原理】:实际就是创建一个子类对象,将其当成父类对象来使用.
语法格式:父类类型 对象名 = new 子类类型()
Animal animal = new Cat("元宝",2);
//animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换
eat()
方法class Animal{
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(age + "岁的" + name + "正在吃东西");
}
}
class Cat extends Animal {
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(age + "岁的" + name + "正在吃猫粮");
}
}
class Dog extends Animal {
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(age + "岁的" + name + "正在吃狗粮");
}
}
直接赋值
类型的向上转型,将子类对象的引用给到父类对象。然后再将这个对象作为参数传递进去,就可以根据不同引用调用不同的行为public class Test1 {
public static void eat(Animal animal)
{
animal.eat();
}
public static void main(String[] args) {
Animal animal1 = new Animal("动物",3);
Animal animal2 = new Cat("加菲猫",2);
Animal animal3 = new Dog("哈士奇",1);
eat(animal1);
eat(animal2);
eat(animal3);
}
}
方法传参
很简单,我们连对象都不需要创建,只需要直接将三种不同对象的引用作为实参传递给到eat()
中的形参接受,就可以产生【向上转型】public class Test1 {
public static void eat(Animal animal)
{
animal.eat();
}
public static void main(String[] args) {
eat(new Animal("动物",3));
eat(new Cat("加菲猫",2));
eat(new Dog("哈士奇",1));
}
}
向上转型
public static void eat(Animal animal)
{
animal.eat();
}
String
字符类型,在方法中通过判断外界传入进来的字符串然后对应地进行返回Cat对象的引用
;Dog对象的引用
;null
public static Animal BuyAnimal(String var)
{
if(var.equals("猫")){
return new Cat("加菲猫",2);
}else if(var.equals("狗")){
return new Dog("哈士奇",1);
}else{
return null;
}
}
Animal animal1 = BuyAnimal("猫");
eat(animal1);
Animal animal2 = BuyAnimal("狗");
eat(animal2);
Animal animal3 = BuyAnimal("兔");
eat(animal3);
return null
空指针异常
上述便是向上转型的三种场景。学会辨别和使用即可
【优点】:让代码实现更简单灵活,这个从上面的三个不同场景就可以看得出来
【缺点】:不能调用到子类特有的方法
Dog
类中写了一个它自己独有的方法lookdoor()class Dog extends Animal {
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(age + "岁的" + name + "正在吃狗粮");
}
public void lookdoor(){
System.out.println(name + "在看门");
}
}
【注意事项】
接下去我们来讲讲向下转型,这种类型的转化不太安全,如果没有特殊需求,不建议使用
无法调用子类独有的方法
这个问题,其实向下转型就可以解决,代码如下Animal animal1 = new Dog("哈士奇",1);
animal1.eat();
//animal1.lookdoor();
Dog dog = (Dog) animal1;
dog.lookdoor();
animal
强转成为Dog狗类
的对象,这样的话其实就可以去调用子类中特有的方法了那为什么说向下转型不安全呢,因为它存在安全隐患
Animal animal1 = new Cat("加菲猫",2);
animal1.eat();
//animal1.lookdoor();
Dog dog = (Dog) animal1;
dog.lookdoor();
Dog狗类
变为了Cat猫类
,此时animal就得到了猫类对象的引用,但是在下面可以看到如果将这个animal强转为Dog狗类
的对象其实就会出问题了ClassCastException —— 类型转换异常
向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。
Java中为了提高向下转型的安全性,引入了 instanceof ,如果该表达式为true,则可以安全转换
instanceof
这个关键字进行了一下判断,看看animal1是否获取到了Dog类的引用,若是才可以进行强制类型转化,若不是的话就不会进行任何操作Animal animal1 = new Cat("加菲猫",2);
animal1.eat();
//animal1.lookdoor();
if(animal1 instanceof Dog){ //判断一下animal1是否获取到了Dog类的引用
Dog dog = (Dog) animal1;
dog.lookdoor();
}
如果对instance关键字感兴趣的可以看看官方的文档 ——> instanceof关键字
可能在上面这一系列说来有点难分辨,我们再来对比看看
Animal animal1 = new Cat
可以看成是猫归属于一个动物类,那猫一定是属于动物的Dog dog = (Dog) animal1
其实就要去思考把动物归属于狗,这其实是说不通的,难道只要是动物就一定是狗吗?那可不一定,动物可多的是来总结一下本文所学到的内容
无法调用子类特有的方法
instanceof
关键字进行一个判断,只有父类接收到了这个子类的引用,才可以强转为这个子类的对象2023年1月22日,大年初一记