![](/img/trans.png)
[英]How to call the superclass implementation of an overridden method from inside the superclass in Java?
[英]How to call the overridden method of a superclass?
如何在代碼中用myAnimal
實例調用Animal
類的吃喝方法?
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("Cat Eats");
}
@Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = myCat;
myAnimal.eat();
myAnimal.drink();
}
}
我得到的輸出:
Cat Eats
Cat Drinks
Cat Eats
Cat Drinks
這是我的預期輸出:
Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
你不能做你想做的事。 多態性的工作方式是做你所看到的。
基本上,貓總是知道它是一只貓,並且無論您是否將其視為貓,貓科動物,貓科動物,貓科動物,貓形目,食肉動物,Theria,哺乳動物,脊椎動物,脊索動物,Eumetazoa,動物界,動物,對象,或其他任何東西:-)
在這里,您可以選擇要調用的方法:
public class Cat extends Animal {
public void superEat() {
super.eat();
}
public void superDrink() {
super.drink();
}
@Override
public void eat() {
System.out.println("Cat Eats");
}
@Override
public void drink() {
System.out.println("Cat Drinks");
}
}
這一行:
Animal myAnimal = myCat;
將變量myAnimal
分配給您之前創建的對象myCat
。 因此,當您在那之后調用myAnimal.eat()
時,實際上是在調用原始 myCat 對象的方法,該方法輸出Cat Eats
。
如果要輸出Animal Eats
,則必須將Animal
實例分配給變量。 因此,如果您改為這樣做:
Animal myAnimal = new Animal()
變量 myAnimal 將是Animal
的一個實例,因此將覆蓋之前對Cat
的賦值。
如果您在此之后調用myAnimal.eat()
,則實際上是在調用您創建的Animal
實例的eat()
方法,該方法將輸出Animal Eats
。
結論:您的代碼應為:
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("Cat Eats");
}
@Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = new Animal();
myAnimal.eat();
myAnimal.drink();
}
}
這與實例方法的情況相反。
在實例方法的情況下,調用對象的實際類的方法。
class ABCD { int x = 10; static int y = 20; public String getName() { return "ABCD"; } } class MNOP extends ABCD { int x = 30; static int y = 40; public String getName() { return "MNOP"; } } public static void main(String[] args) { System.out.println(new MNOP().x + ", " + new MNOP().y); ABCD a = new MNOP(); System.out.println(ax); // 10 System.out.println(ay); // 20 System.out.println(a.getName()); // MNOP }
在此示例中,盡管對象 myCat 被分配給 Animal 對象引用( Animal myAnimal = myCat
),但 Actual 對象是Cat
類型,它的行為就像一只貓。
希望這可以幫助。
您可以為類 Animal 創建構造函數,該構造函數將另一個Animas 作為參數,並基於提供的一個創建新實例。
public class Animal {
//some common animal's properties
private int weight;
private int age;
public Animal() {
// empty.
}
public Animal(final Animal otherAnimal) {
this.weight = otherAnimal.getWeight();
this.age = otherAnimal.getAge();
}
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
// setters and getters.
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("Cat Eats");
}
@Override
public void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
// note: myAnimal is not a Cat, it's just an Animal.
Animal myAnimal = new Animal(myCat);
myAnimal.eat();
myAnimal.drink();
}
}
如果您將每個類中的方法設為靜態,它應該可以工作。
public class Animal {
public static void eat() {
System.out.println("Animal Eats");
}
public static void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
@Override
public static void eat() {
System.out.println("Cat Eats");
}
@Override
public static void drink() {
System.out.println("Cat Drinks");
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = myCat;
myAnimal.eat();
myAnimal.drink();
}
}
上面的代碼將給出以下輸出
Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
幾點建議:
不要將子類引用傳遞給超類,並且必須為重寫的方法調用超類方法之外的方法。 從超類實例調用超類方法。
Animal myAnimal = new Animal(); myAnimal.eat();
如果要從子類調用超類方法,使用 super.methodName() 顯式調用超類方法名;
public void eat() { super.eat(); System.out.println("Cat Eats"); }
你可以使用 super 關鍵字實現你想要的,它允許訪問被覆蓋的方法。
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
public void eat() {
System.out.println("Cat Eats");
}
public void drink() {
System.out.println("Cat Drinks");
}
public void printMessage(){
super.eat();
super.drink();
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
myCat.printMessage();
}
}
請不要對這個答案投票......你可以對另一個投票:-) 這是一個糟糕的答案,但顯示了你將如何做你想做的事情......糟糕。
public class Main
{
public static void main(final String[] argv)
{
Child child;
Parent parent;
child = new Child();
parent = child;
child.a();
parent.a();
child.otherA();
parent.otherA();
}
}
class Parent
{
public void a()
{
System.out.println("Parent.a()");
}
public void otherA()
{
// doesn't matter what goes here... really should be abstract
}
}
class Child
extends Parent
{
@Override
public void a()
{
System.out.println("Child.a()");
}
@Override
public void otherA()
{
super.a();
}
}
貓不能停止成為貓,即使它是動物。 貓會吃貓會喝貓的方式。 它可能類似於 Animal 所做的事情,這就是它覆蓋該方法的原因。 如果你想讓它做動物默認做的事情,不要覆蓋。 您可能可以通過反射做一些奇怪的事情,並制作訪問父方法的單獨方法,例如:
public void superDrink() {
Animal.class.getMethod("drink").invoke();
}
但這可能有點矯枉過正,你不覺得嗎?
當然,這可能行不通,因為它不是靜態的。
public class Main {
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
Animal myAnimal = new Animal();
myAnimal.eat();
myAnimal.drink();
}
}
public class Animal {
public void eat(){
System.out.println("Animal eat() called");
}
public void drink(){
System.out.println("Animal drink() called");
}
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("Cat eat() called");
}
@Override
public void drink() {
System.out.println("cat drink() called");
}
}
輸出:
貓吃()調用
貓喝()調用
動物吃()調用
動物飲料()調用
您需要創建超類Animal
的對象,或者另一個選項是在子類方法中使用關鍵字super
,例如super.eat()
或super.drink()
您可以通過對代碼進行一些小的更改來做您想做的事情。 自然地,Animal 類的方法已被覆蓋,您不能簡單地通過更改引用類型來訪問它們。 相反,你可以稍微改變一下 eat 和 Drink 函數的定義,如下所示。
class Animal{
public void eat(boolean randomBoolean){
System.out.println("Animal eats");
}
public void drink(boolean randomBoolean){
System.out.println("Animal drinks");
}
}
class Cat extends Animal{
public void eat(boolean wantOverriden){
if(wantOverriden){
boolean randomBooleanValue=true|false;
super.eat(randomBooleanValue);
}
else{
System.out.println("Cat eats");
}
}
public void drink(boolean wantOverriden){
if(wantOverriden){
boolean randomBooleanValue=true|false;
super.drink(randomBooleanValue);
}
else{
System.out.println("Cat drinks");
}
}
}
現在您應該能夠通過 Cat 類對象訪問 Animal 類的覆蓋方法,只需傳入一個布爾值來指示您是否要這樣做,例如:
Cat c=new Cat();
c.eat(false); //Indicating that you dont want to access the overriden method
c.drink(false); //Indicating that you dont want to access the overriden method
c.eat(true); //Indicating that you want to access the overriden method
c.drink(true); //Indicating that you want to access the overriden method
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.