コード内のAnimal
インスタンスでmyAnimal
クラスのeat and drinkメソッドを呼び出すにはどうすればよいですか?
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
あなたがしたいことはできません。ポリモーフィズムが機能する方法は、あなたが見ていることをすることです。
基本的に、猫は猫であることを常に知っており、猫、Felis、Felinae、Felidae、Feliformia、Carnivora、Theria、Mammalia、Vertebrata、Chordata、Eumetazoa、Animalia、Animal、オブジェクト、またはその他:-)
ここで、呼び出すメソッドを選択するオプションがあります。
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()
を呼び出すと、実際には_Cat Eats
_を出力する元のmyCatオブジェクトのメソッドを呼び出しています。
_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(a.x); // 10
System.out.println(a.y); // 20
System.out.println(a.getName()); // MNOP
}
この例では、オブジェクトmyCatがAnimalオブジェクト参照に割り当てられていますが、(Animal myAnimal = myCat
)ActualオブジェクトはCat
型であり、猫のように動作します。
お役に立てれば。
各クラスのメソッドを静的にすると、動作するはずです。
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のコンストラクターを作成できます。このコンストラクターは、別の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();
}
}
いくつかの提案:
子クラス参照をスーパークラスに渡さないでください。ただし、オーバーライドされたメソッドに対してスーパークラスメソッドを呼び出す必要がある場合を除きます。スーパークラスインスタンスからスーパークラスメソッドを呼び出します。
Animal myAnimal = new Animal();
myAnimal.eat();
子クラスからスーパークラスメソッドを呼び出す場合は、super.methodName()を使用してスーパークラスメソッド名を明示的に呼び出します。
public void eat() {
super.eat();
System.out.println("Cat Eats");
}
この答えには投票しないでください...他の答えには投票できます:-)これは悪い答えですが、あなたがしようとしていることをどうやって行うかを示しています...貧弱です。
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();
}
}
たとえ猫であっても、猫は猫であることをやめられません。猫は猫のように食べ、猫は飲みます。それは動物がすることと似ているかもしれません。それがメソッドをオーバーライドする理由です。動物がデフォルトで行うことを実行する場合は、オーバーライドしないでください。おそらくリフレクションを使用して奇妙なことを行い、次のような親メソッドにアクセスする別のメソッドを作成できます。
public void superDrink() {
Animal.class.getMethod("drink").invoke();
}
しかし、それはやり過ぎかもしれませんね。
もちろん、静的ではないため、おそらく動作しません。