[英]Casting objects in Java
我對用Java轉換對象的含義感到困惑。
說你有...
Superclass variable = new Subclass object();
(Superclass variable).method();
這是怎么回事 變量類型會更改嗎,還是變量內的對象發生了更改? 很迷茫。
看一下這個樣本:
public class A {
//statements
}
public class B extends A {
public void foo() { }
}
A a=new B();
//To execute **foo()** method.
((B)a).foo();
假設您有一個超類Fruit和香蕉子類,並且有一個方法addBananaToBasket()
例如,該方法將不接受葡萄 ,因此您要確保將香蕉添加到籃子中。
所以:
Fruit myFruit = new Banana();
((Banana)myFruit).addBananaToBasket();
is這稱為鑄造
您引用的示例在Java中稱為Upcasting。
它創建一個帶有超類變量指向它的子類對象。
該變量不會改變,它仍然是超類的變量,但它指向子類的對象。
例如,假設您有機器和相機兩個類; 相機是機器的子類
class Machine{
public void start(){
System.out.println("Machine Started");
}
}
class Camera extends Machine{
public void start(){
System.out.println("Camera Started");
}
public void snap(){
System.out.println("Photo taken");
}
}
Machine machine1 = new Camera();
machine1.start();
如果執行上述語句,它將創建一個Camera類的實例,並指向Machine類的引用。因此,現在輸出將是“ Camera Started ”,該變量仍然是Machine類的引用。 如果嘗試使用machine1.snap();
該代碼將無法編譯
這里的要點是所有照相機都是機器,因為照相機是機器的子類,但是所有機器都不是照相機。 因此,您可以創建子類的對象並將其指向超類引用,但是您不能要求超類引用執行子類對象的所有功能(在我們的示例中, machine1.snap()
不會編譯)。 超類引用只能訪問超類已知的功能(在我們的示例中是machine1.start()
)。 您不能要求機器參考快速進行操作。 :)
Superclass variable = new subclass object();
這只是創建一個子類類型的對象,但是將其分配給超類類型。 所有子類的數據均已創建等,但變量無法訪問子類的數據/功能。 換句話說,您不能調用任何方法或訪問特定於子類的數據,只能訪問超類的東西。
但是,您可以將Superclassvariable強制轉換為Subclass並使用其方法/數據。
有時,您可能希望接收“父代”引用作為參數,而您可能希望在其中進行特定於孩子的操作。
abstract class Animal{
public abstract void move();
}
class Shark extends Animal{
public void move(){
swim();
}
public void swim(){}
public void bite(){}
}
class Dog extends Animal{
public void move(){
run();
}
public void run(){}
public void bark(){}
}
...
void somethingSpecific(Animal animal){
// Here you don't know and may don't care which animal enters
animal.move(); // You can call parent methods but you can't call bark or bite.
if(animal instanceof Shark){
Shark shark = (Shark)animal;
shark.bite(); // Now you can call bite!
}
//doSomethingSharky(animal); // You cannot call this method.
}
...
在上面的方法中,您可以傳遞“鯊魚”或“狗”,但是如果您有這樣的情況怎么辦:
void doSomethingSharky(Shark shark){
//Here you cannot receive an Animal reference
}
該方法只能通過傳遞鯊魚引用來調用,因此,如果您有動物(並且深深是鯊魚),則可以這樣調用它:
Animal animal...
doSomethingSharky((Shark) animal)
最重要的是,您可以使用“父對象”引用,當您不關心“父對象”的實現並且使用強制轉換將“子對象”用作特定對象時,通常會更好,這將是完全相同的對象,但是您的引用知道這一點,如果不進行強制轉換,則引用將指向同一對象,但不能確定其類型是Animal,因此僅允許您調用已知方法。
假設您有A類作為超類,而B類則是A的子類。
public class A {
public void printFromA(){
System.out.println("Inside A");
}
}
public class B extends A {
public void printFromB(){
System.out.println("Inside B");
}
}
public class MainClass {
public static void main(String []args){
A a = new B();
a.printFromA(); //this can be called without typecasting
((B)a).printFromB(); //the method printFromB needs to be typecast
}
}
例如,您有Animal超類和Cat子類。 方法。
class Animal{
public void walk(){
}
}
class Cat extends Animal{
@Override
public void walk(){
}
public void speak(){
}
public void main(String args[]){
Animal a=new Cat();
//a.speak(); Compile Error
// If you use speak method for "a" reference variable you should downcast. Like this:
((Cat)a).speak();
}
}
在此示例中,您的超類變量告訴子類對象實現超類的方法。 這是Java對象類型轉換的情況。 這里的method()函數最初是超類的方法,但是超類變量無法訪問超類中不存在的子類對象的其他方法。
在某些情況下,我們不能保證集合或明智元素中存在的元素或對象的類型,在強制檢索時,我們應該執行類型轉換,否則會出現編譯時錯誤。
數組始終是類型安全的,這是我們可以為數組內存在的元素類型提供保證。 為了實現類型安全,我們必須使用類型轉換。
必須進行強制轉換才能告訴您您正在調用子方法而不是父方法。 所以它一直在下降。 但是,如果該方法已經在父類中定義並且在子類中被覆蓋,則無需任何強制轉換。 這里是一個例子:
class Parent{
void method(){ System.out.print("this is the parent"); }
}
class Child extends Parent{
@override
void method(){ System.out.print("this is the child"); }
}
...
Parent o = new Child();
o.method();
((Child)o).method();
這兩個方法的調用都將打印:“這是孩子”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.