簡體   English   中英

用Java轉換對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM