美好的一天,Javarash 人。我开始收到有关在 Java 中转换引用类型的问题。为了不每次都重复同样的事情,我决定写一篇短文。
首先,我们来看看什么是类型转换。
类型转换(类型转换)是将一种类型的变量值转换为另一种类型的值。让我们看一个例子来了解它是什么以及它与什么一起吃。我们有一些类层次结构(参见图 1)。这里可以看到层次结构的所有类,谁继承了谁,以及每个类的方法。 有扩张内收和收缩内收。我们看到该类Cat
是该类的后代Pet
。Pet
反过来,又是班级的继承人Animal
。当我们写:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
这是一种扩展的演员阵容(或隐式的演员阵容)。我们扩展了链接animalCat
和animalDog
。它们指的是对象Cat
和Dog
。通过这样的强制转换,我们无法animalCat/animalDog
通过位于 中Cat/Dog
但不在 中的链接调用方法Animal
。 缩小(或显式)强制转换发生在相反的方向:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
我们已经清楚地表明了我们想要将此对象转换为什么类型。 不过要小心!!! 如果你这样做:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
编译器将跳过这段代码。但RunTime
它会向你抛出:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
看到Cat
有YorkshireTerrier
两个不同的类。为了避免在缩小转换期间出现ClassCastExceptioninstanceof
,请使用.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
如果animalCat
是YorkshireTerrier
,则分配将会发生,如果不是,则什么也不会发生。
现在,如果我们丢失方法并可能出现此类错误,为什么这是必要的
让我们看一下我根据图 1 中的图表编写的代码。1 . 班级Animal
public abstract class Animal
{
String name;
int age;
String nameOfClass = getClass().getSimpleName();
public void eat(){
System.out.println(nameOfClass + ": Omnomnom");
}
public void sleep(){
System.out.println(nameOfClass + ": Z-z-z-z");
}
}
一个WildAnimal
继承自的类Animal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
一个Pet
继承自的类Animal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
一个Fox
继承自的类WildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
一个Wolf
继承自的类WildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
一个Cat
继承自的类Pet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
一个YorkshireTerrier
继承自的类Pet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
想象一下情况。我们需要将所有动物收集在一个列表中,喂养它们,然后让它们上床睡觉。如果我们创造动物,这很容易做到ArrayList
(Animal
)。然后我们为每个动物调用相应的方法:
public class ZOO
{
public static void main(String[] args)
{
List<Animal> allAnimals = new ArrayList<>();
allAnimals.add(new Cat());
allAnimals.add(new Wolf());
allAnimals.add(new Fox());
allAnimals.add(new YorkshireTerrier());
for (Animal animal : allAnimals)
{
animal.eat();
animal.sleep();
}
}
}
我无法animal
调用该方法bark()
或sleepOnKeyboard()
. 因为该表allAnimals
包含一只猫、一只狼、一只约里克和一只狐狸,但它们被简化为Animal
。而且他们只有 中的方法Animal
。这很好,因为如果我们可以调用所有的方法,那么为什么我们需要一只睡在键盘上的狼,或者一个偷鸡的约里克呢?感谢您的关注。我希望这篇文章对您有用。欢迎批评和指正)
GO TO FULL VERSION