如何使用现有基础 class 对象构造派生 class
How to construct derived class with existing base class object
我需要从现有的 Fruit 对象构造 class 例如 Apple 或 Strawberry。
这是我的水果class:
public class Fruit {
int somevariable;
Thread somethread;
public Fruit(int somevariable) {
this.somevariable = somevariable;
this.somethread = new Thread() {
public void run() { /* Something here */ }
}
this.somethread.start();
}
public Fruit(Fruit fruit) {
this.somevariable = fruit.somevariable;
this.somethread = fruit.somethread;
}
}
这是我的苹果和草莓class:
public class Apple extends Fruit {
public Apple(Fruit fruit) {
super(fruit);
}
}
public class Strawberry extends Fruit {
public Strawberry(Fruit fruit) {
super(fruit);
}
}
我有这样的 HashMap:
HashMap<Integer, Fruit> fruits = new HashMap<>();
起初,我是这样添加水果的:
(我只知道现在是这个水果,我不能马上加一个苹果或者一个草莓。)
fruits.put(17, new Fruit(4));
fruits.put(24, new Fruit(8));
fruits.put(95, new Fruit(12));
当我发现它是哪种水果时,我需要用苹果或草莓替换水果对象(与超级对象相同的水果对象)。当然没有停止somethread。
我就是这样解决的:
fruits.replace(17, new Strawberry(fruits.get(17)));
fruits.replace(24, new Apple(fruits.get(24)));
fruits.replace(95, new Strawberry(fruits.get(95)));
我的问题是:
这可以变得更简单吗?我的解决方案正确吗?
还有一个问题,如果我在一个草莓中有经常被其他线程调用的函数,如何确保在替换hashmap值时没有问题?
非常感谢您的帮助:)
至于并发修改使用Collections.synchronizedMap或者ConcurrentHashMap.
至于制作更容易,你能具体说明你想让什么更容易吗?不必编写构造函数?
回答问题“这可以更简单吗?我的解决方案正确吗?”
是的。你根本不必在这里做 replace
因为你放在地图中的对象是 Fruit
类型,当你需要对其进行操作时就可以转换它。
如果您希望更具体,也可以像 obj instanceof Fruit
这样检查。
此外,正如@miszcz2137 也提到的那样,您的代码看起来一点也不安全,并发修改 迫在眉睫。
优先组合而不是继承。 子class具体class(Object
除外,尽管具体是一种"deprecated" 目前)通常不是很好。
Fruit
应该有一个 FruitType
(或更好的名称)。根据需要委派。
另请注意,在原始代码中,Runnable
(编辑: Thread
没有被覆盖 run
)在原始 Fruit
实例的上下文中创建。此外,该线程最初会看到 Fruit
不能保证完全初始化。
我需要从现有的 Fruit 对象构造 class 例如 Apple 或 Strawberry。
这是我的水果class:
public class Fruit {
int somevariable;
Thread somethread;
public Fruit(int somevariable) {
this.somevariable = somevariable;
this.somethread = new Thread() {
public void run() { /* Something here */ }
}
this.somethread.start();
}
public Fruit(Fruit fruit) {
this.somevariable = fruit.somevariable;
this.somethread = fruit.somethread;
}
}
这是我的苹果和草莓class:
public class Apple extends Fruit {
public Apple(Fruit fruit) {
super(fruit);
}
}
public class Strawberry extends Fruit {
public Strawberry(Fruit fruit) {
super(fruit);
}
}
我有这样的 HashMap:
HashMap<Integer, Fruit> fruits = new HashMap<>();
起初,我是这样添加水果的: (我只知道现在是这个水果,我不能马上加一个苹果或者一个草莓。)
fruits.put(17, new Fruit(4));
fruits.put(24, new Fruit(8));
fruits.put(95, new Fruit(12));
当我发现它是哪种水果时,我需要用苹果或草莓替换水果对象(与超级对象相同的水果对象)。当然没有停止somethread。
我就是这样解决的:
fruits.replace(17, new Strawberry(fruits.get(17)));
fruits.replace(24, new Apple(fruits.get(24)));
fruits.replace(95, new Strawberry(fruits.get(95)));
我的问题是:
这可以变得更简单吗?我的解决方案正确吗?
还有一个问题,如果我在一个草莓中有经常被其他线程调用的函数,如何确保在替换hashmap值时没有问题?
非常感谢您的帮助:)
至于并发修改使用Collections.synchronizedMap或者ConcurrentHashMap.
至于制作更容易,你能具体说明你想让什么更容易吗?不必编写构造函数?
回答问题“这可以更简单吗?我的解决方案正确吗?”
是的。你根本不必在这里做 replace
因为你放在地图中的对象是 Fruit
类型,当你需要对其进行操作时就可以转换它。
如果您希望更具体,也可以像 obj instanceof Fruit
这样检查。
此外,正如@miszcz2137 也提到的那样,您的代码看起来一点也不安全,并发修改 迫在眉睫。
优先组合而不是继承。 子class具体class(Object
除外,尽管具体是一种"deprecated" 目前)通常不是很好。
Fruit
应该有一个 FruitType
(或更好的名称)。根据需要委派。
另请注意,在原始代码中,Runnable
(编辑: Thread
没有被覆盖 run
)在原始 Fruit
实例的上下文中创建。此外,该线程最初会看到 Fruit
不能保证完全初始化。