这不完全是隐式类型转换的定义,但我很好奇我用这个标准打破了多少标准......
我在Java中创建一个抽象类,它基本上根据传递给构造函数的字符串来转换变量。
例如:
public abstract class MyClass {
Object that;
public MyClass(String input){
if("test1".equals(input){
that = new Test1();
}
else{
that = new Test();
}
}
public void doSomething(){
if(that instanceof Test1){
//specific test1 method or variable
} else if(that instanceof Test2)}
//specific test2 method or variable
} else {
//something horrible happened
}
}
}
你看到我得到了什么?现在我遇到的问题是我的编译器希望我在that
方法中明确地将Test1
转换为Test2
或doSomething
- 我理解,因为编译器赢了'假设它是某种对象类型,即使if语句几乎保证了类型。
我想我得到的是,这是一个有效的解决方案吗?
我有其他类基本上都做同样的事情,但根据一个简单的差异使用两个不同的库,并且这个类可以帮助我轻松跟踪并对所有其他对象进行更改。
答案 0 :(得分:10)
你是对的。这是在设计中实现多态性的可怕方法。你考虑过使用工厂吗?策略对象?听起来你想要实现的目标可以使用这些模式(以及其他模式)的组合以更松散耦合的方式实现。
对于doSomething
的多态性,例如:
interface Thing {
public void doThing();
}
class Test1 implements Thing {
public void doThing() {
// specific Test1 behavior
}
}
class Test2 implements Thing {
public void doThing() {
// specific Test2 behavior
}
}
class MyClass {
Thing _thing;
public void doSomething() {
_thing.doThing(); // a proper polymorphism will take care of the dispatch,
// effectively eliminating usage of `instanceof`
}
}
当然,您需要在一组公共接口下统一Test1
和Test2
(以及其他具体Thing
类,即现有和计划的)的行为。< / p>
PS:此设计通常称为Strategy Pattern。
答案 1 :(得分:1)
我会创建一个单独的类文件。所以你会有这样的事情: 1.你抽象“MyClass” - &gt;在“MyClass”中定义一个抽象方法调用doSomething ...这将强制该方法的特定实现到它的子类。 2. Test1将是MyClass的实现,它将包含doSomething方法的实现 3.创建一个实用程序类,它执行检查“instanceOf”,检查不应该在它所属的构造函数中。
所以最后你会有3个类文件,一个Abstract类,Abstract的实现和一个执行“instanceOf”检查的类。我知道这听起来很多,但它是正确的设计方式,因为我认为你正在尝试做。你应该拿起一本设计模式书,我认为这对你有很多帮助。
答案 2 :(得分:1)
通过在此类之外移动对象创建,可以更好地满足Open-Closed principle。
考虑更改构造函数以接受实现接口的对象。
public MyClass {
public MyClass( ITest tester ) { m_tester = tester; }
public void doSomething(){ m_tester.doTest(); }
}
这样就可以在不修改代码的情况下更改类的行为(打开扩展名)(关闭修改)。
答案 3 :(得分:1)
更好的方法是创建一个interface,它将指定一组可以保证在对象上调用的方法。
以下是一个例子:
public interface TestInterface
{
void doTest();
}
现在您可以编写类来实现此接口。这意味着您需要为界面中的所有方法提供完整定义,在本例中为doTest()
。
public class Test implements TestInterface
{
public void doTest()
{
// do Test-specific stuff
}
}
public class Test1 implements TestInterface
{
public void doTest()
{
// do Test1-specific stuff
}
}
看起来真无聊,毫无意义,对吧?我听到你说很多额外的工作。
真值来自调用代码...
public abstract class MyObject
{
Test that;
// [...]
public void doSomething()
{
that.doTest();
}
}
不,如果陈述,没有实例,没有丑陋的块,没有。这一切都转移到了公共接口方法中的类定义(同样,这里是doTest()
)。