【问题标题】:Decide type of request class?决定请求类的类型?
【发布时间】:2013-10-17 07:17:11
【问题描述】:

我有以下三个课程。

SuperClass.java
SubClass1 extends SuperClass
SubClass2 extends SuperClass

我有一个方法可以接受SuperClass 类型的方法参数。

getResult(SuperClass request){
//Here the request can be of SubClass1 type or SubClass2 type.

}

这里的request 可以是SubClass1 类型或SubClass2 类型。

getResult() 方法中基于请求类型我需要做一些逻辑。

要找出类型,我可以使用instanceof 运算符,如下所示。

if(request instanceof SubClass1){
//do something
}else if(request instanceof SubClass2){
//dosomething
}

有没有最好的方法来找出请求的类型?

谢谢!

【问题讨论】:

  • java中没有instance of,但是有instanceof
  • @javaBeginner 我编辑了我的问题..
  • 最好的方法是不要使用 instanceof,因为它在大多数情况下指向设计异味。再次考虑您的设计。您提供的 sn-ps 数量不足以建议其他恕我直言。
  • @NarendraPathai,感谢您的回复。基本上我的超类将有一些共同的属性。我的想法不是有两个单独的方法来接受 subclass1 和 subclass2,而是计划使用带有超类类型参数的单个方法..
  • 不鼓励使用 instanceof 的唯一原因是因为它表明未正确利用多态行为,并且有点像非 OO 编程。但这并不意味着您永远不必使用它,在某些情况下您可以使用它,请阅读@Jon Skeet 在stackoverflow.com/questions/7453288/…中的回答@

标签: java spring jakarta-ee


【解决方案1】:

尽量避免使用instanceof 关键字。

不鼓励使用 instanceof 的原因是它不是 OOP。 对象的调用者/用户应该没有理由知道它是哪个具体类的实例,超出了它声明的变量的类型。 如果您需要子类中的不同行为,请添加一个方法并以不同方式实现它们。

基本方法:我会写这样的东西:

enum Types{ SUB_1, SUB_2 }

public class SubClass1 extends SuperClass{
  public Types type = Types.SUB_1;
} 

public class SubClass2 extends SuperClass{
  public Types type = Types.SUB_2;
} 

和:

if(Types.SUB_1 == request.type){
  //do something
}else if(Types.SUB_2 == request.type){
  //do something
}

正确的方式(在我看来)我会在你的情况下使用多态性。

多态性 - 相同的消息发送到不同的对象,导致行为依赖 关于接收消息的对象的性质。

意思是:

 public interface SuperClassItf{
  public void doStuff();
 }

 public class SubClass1 extends SuperClassItf{
     public void doStuff(){
          // do 1
       }
    } 

    public class SubClass2 extends SuperClassItf{
     public void doStuff(){
        // do 2
     }
    } 

主要

getResult(SuperClassItf request){
   request.doStuff(); //polymorphic method call
}

【讨论】:

  • 你能告诉我为什么不鼓励使用 instanceof 关键字吗?谢谢!
  • 你为什么要这样做?
  • 这个我也不懂。在这里使用 instanceof 有什么好处?
  • 因为instanceof 很慢。
  • @ZagorulkinDmitry 你有你建议的基准吗? instanceof 在 Java 1.3 天的时候很慢,改进了很多。
【解决方案2】:

来自我的评论:

不鼓励使用 instanceof 的唯一原因是因为它表明 多态行为没有得到正确利用,有点像 非面向对象编程。但这并不意味着你永远不必使用它, 有一些条件可以使用它。

运行时多态

现在您可以利用覆盖(运行时多态性),这是一种正确的做事方式。

abstract class SuperClass{
   public abstract Result getResult();
}

class SubClass1 extends SuperClass{
   @Override
   public Result getResult(){
      //logic
   }
}


class SubClass2 extends SuperClass{
   @Override
   public Result getResult(){
      //logic
   }
}

//calling 

getResult(SuperClass request){
   Result r = request.getResult();
}

【讨论】:

    【解决方案3】:

    另一种方法是运行时多态性。这是给你的示例代码。

    public class SuperClass
    {
    public void doSomething(){}
    }
    public class SubClass1 extends SuperClass{
      public void doSomething(){}
    } 
    
    public class SubClass2 extends SuperClass{
      public void doSomething(){}
    }
    
    getResult(SuperClass request){
    
     request.doSomething();
    
    }
    

    【讨论】:

    • 抽象类完全没问题,它也可以有非抽象方法。
    • @user755806 不是真的,事实上,在子类之间实现变化的方法可能更好abstract
    【解决方案4】:

    为什么不把getResult()放在一个接口中,让逻辑在抽象的SuperClass具体子类中执行?

    public interface ResultProvider {
        public Result getResult();
    }
    
    public abstract class SuperClass implements ResultProvider {
        ...
    }
    
    public SubClass1 extends SuperClass {
        public Result getResult() {
            ...
        }
    }
    
    public SubClass2 extends SuperClass {
        public Result getResult() {
            ...
        }
    }
    

    【讨论】:

    • 你能告诉我为什么不鼓励使用 instanceof 运算符吗?谢谢!
    • 如果这与 instanceof 相同,并且您在答案中提出问题。这不是答案。
    猜你喜欢
    • 2011-11-19
    • 1970-01-01
    • 2017-10-19
    • 2021-08-17
    • 2017-09-30
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多