【问题标题】:Java Base Object Multi Type VariableJava 基础对象多类型变量
【发布时间】:2010-08-22 09:47:36
【问题描述】:

我确信这在 Java 以 OOP 为中心的情况下非常普遍。在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 中使用多态鸭子类型并不是一个好主意,但是因为我认为我无法避免它。是动态使用子类方法重新分配变量的强制转换版本的唯一方法,即,我得到一个错误;

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();
}

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

【问题讨论】:

  • 我不太明白你的问题,Mammal 实际上会接受 Mammal 的任何子类。
  • 我还没有完成静态类型的 OOP,所以我认为这行不通。我以为你只能覆盖方法中的类型。
  • 演员表暗示您的设计存在错误。如果你需要知道某物是什么类型,你应该把它保存为那个类型的东西。

标签: java oop class variables extend


【解决方案1】:

如果您有以下情况:

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

那么DogMammal 的子类型。 Cat 也是Mammal 的子类型。这种类型多态性实际上允许您执行以下操作:

Mammal x;
x = new Dog(); // fine!
x = new Cat(); // also fine!

如果事实上以后有以下内容:

class Platypus extends Mammal {...} // yes it's true!

那么你也可以这样做:

x = new Platypus(); // fine!

这种多态子类型关系是面向对象编程的基本原则之一。

另见


开启instanceof 类型比较运算符

假设我们有以下内容:

class Mammal { void lactate(); }
class Dog extends Mammal { void bark(); }
class Cat extends Mammal { void meow(); }

然后你可以使用instanceof类型比较运算符(§15.20.2)来做这样的事情:

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也有办法做到这一点;这只是一个简单的例子。

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

相关问题


反思

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

另见

【讨论】:

  • 好的,谢谢,这就是我想知道的。但这确实留下了一个问题,你怎么知道它是否具有吠叫或喵叫方法?只需使用 if-then 检查类型和分支代码?还是 java 做它躲避类型的 Ruby/Javascript 的事情?
  • 如果你想在一个扩展父类的对象上调用一个方法,并添加一个父类没有的方法,你必须将它转换为它真正的对象或类似的东西
  • 谢谢,我会留意的。我想做的是一个 RPG 数据库的事情。物品的获取方式基本原理相同,但获取方式有所不同;暴民掉落(暴民名称),供应商购买(供应商名称)或任务奖励(任务启动器,任务名称)。
  • @Axpen:几个月前有人问过一个 RPG 风格的问题。基本上它有一对对象之间的交互方法,但是由于 Java 是单调度的,所以代码最终变得非常混乱。不错的解决方案是使用访问者模式。我已经失去了这个问题的链接,但也许其他人可以为你挖掘它;它可能与您正在做的事情有关。
猜你喜欢
  • 2020-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-02-07
  • 2021-09-26
  • 1970-01-01
相关资源
最近更新 更多