Java基本对象多类型变量

Java基本对象多类型变量,java,oop,class,variables,extend,Java,Oop,Class,Variables,Extend,我相信这在以面向对象编程为中心的Java中是非常普遍的。在java中,有没有一种方法可以使基类型变量接受所有继承的子类型?如果我有 class Mammal {...} class Dog extends Mammal {...} class Cat extends Mammal {...} class ABC { private Mammal x; ABC() { this.x = new Dog(); -or- this.x

我相信这在以面向对象编程为中心的Java中是非常普遍的。在java中,有没有一种方法可以使基类型变量接受所有继承的子类型?如果我有

class Mammal {...}
class Dog extends Mammal {...}
class Cat extends Mammal {...}

class ABC {
    private Mammal x;

    ABC() {
        this.x = new Dog();
        -or-
        this.x = new Cat();
    }
}
我需要变量能够接受任何扩展版本,但不是特定的扩展类型

有一些方法我知道,但不想使用。我可以为每个子类型创建一个属性,然后只有一个实际使用的属性。做一个阵列,然后把它推进去

有没有其他想法或方法来获取“基类”类型变量


好吧,因为我知道在Java中使用多态duck类型不是一个好主意,但是因为我认为我无法避免它。是动态使用子类方法重新分配可变ie的铸造版本的唯一方法,我得到了一个错误

Mammal x;
x = new Dog();
System.out.println(x.getClass());
x.breath();
if (x instanceof Dog) {
  x.bark();
} else if (x instanceof Cat) {
  x.meow();
}
说符号没有找到,但这是作品

Mammal x;
x = new Dog();
System.out.println(x.getClass());
x.breath();
if (x instanceof Dog) {
  Dog d = (Dog) x;
  d.bark();
} else if (x instanceof Cat) {
  Cat c = (Cat) x;
  c.meow();
}

最后一个是唯一的方法吗?

如果您有以下条件:

class Mammal {...}
class Dog extends Mammal {...}
class Cat extends Mammal {...}
Mammal x;
x = new Dog(); // fine!
x = new Cat(); // also fine!
class Platypus extends Mammal {...} // yes it's true!
class Mammal { void lactate(); }
class Dog extends Mammal { void bark(); }
class Cat extends Mammal { void meow(); }
那么
哺乳动物
的一个亚型
Cat
也是
哺乳动物的一个亚型。这种类型的多态性实际上允许您执行以下操作:

class Mammal {...}
class Dog extends Mammal {...}
class Cat extends Mammal {...}
Mammal x;
x = new Dog(); // fine!
x = new Cat(); // also fine!
class Platypus extends Mammal {...} // yes it's true!
class Mammal { void lactate(); }
class Dog extends Mammal { void bark(); }
class Cat extends Mammal { void meow(); }
如果事实上以后会出现以下情况:

class Mammal {...}
class Dog extends Mammal {...}
class Cat extends Mammal {...}
Mammal x;
x = new Dog(); // fine!
x = new Cat(); // also fine!
class Platypus extends Mammal {...} // yes it's true!
class Mammal { void lactate(); }
class Dog extends Mammal { void bark(); }
class Cat extends Mammal { void meow(); }
然后,您还可以执行以下操作:

x = new Platypus(); // fine!
这种多态子类型关系是面向对象编程的基本原则之一

另见
  • ,在面向对象编程的上下文中几乎被普遍称为多态性,是一种类型A的能力,它可以像另一种类型B一样出现和使用


在类型比较运算符的
实例上
假设我们有以下情况:

class Mammal {...}
class Dog extends Mammal {...}
class Cat extends Mammal {...}
Mammal x;
x = new Dog(); // fine!
x = new Cat(); // also fine!
class Platypus extends Mammal {...} // yes it's true!
class Mammal { void lactate(); }
class Dog extends Mammal { void bark(); }
class Cat extends Mammal { void meow(); }
然后可以使用
instanceof
类型比较运算符()执行以下操作:

Mammal x = ...;

if (x instanceof Dog) {
   Dog d = (Dog) x;
   d.bark();
} else if (x instanceof Cat) {
   Cat c = (Cat) x;
   c.meow();
}
if (x != null) {
   x.lactate();
}
如果没有
if-else
,也有一些方法可以做到这一点;这只是一个简单的例子

请注意,通过适当的设计,您可以避免某些类型的子类型区分逻辑。例如,如果
Madama
有一个
makeSomeNoise()
方法,您可以简单地调用
x.makeSomeNoise()

相关问题
  • -有时用于模拟双重调度

反思 如果必须处理编译时未知的新类型,则可以求助于反射。请注意,对于一般应用程序,几乎总是有比反射更好的替代方案

另见
  • 有效Java第二版,第53项:首选接口而非反射

我真的不理解你的问题,事实上哺乳动物会接受哺乳动物的任何子类。我没有做过静态类型的OOP,所以我认为这不管用。我认为您只能重写方法中的类型。强制转换意味着您的设计有错误。如果你需要知道什么类型的东西,你应该把它保存为那种类型的东西。好的,谢谢,这就是我想知道的。但这确实留下了一个问题,你如何知道它是否有树皮或喵喵的方法?用if-then检查类型和分支代码?或者java做的是Ruby/Javascript类型的事情吗?如果你想在一个扩展父类的对象上调用一个方法,并添加一个父类没有的方法,你必须将它转换为真实的对象或类似的东西。谢谢,我会关注它。我想做的是一个RPG数据库的事情。获取项目的方法有相同的基本原则,但在获取方式上存在差异;暴徒掉落(暴徒名称)、卖主购买(卖主名称)或任务奖励(任务启动者、任务名称)。@Axpen:几个月前有一个RPG风格的问题被问到。基本上,它在一对对象之间有一个交互方法,但由于Java是单分派的,因此代码最终非常混乱。很好的解决方案是使用访问者模式。我已经失去了这个问题的链接,但也许其他人可以帮你挖掘出来;它可能与您正在做的事情有关。@Axpen:您可能还需要查找
enum
,它在Java中非常强大;