替换switch case:接口 vs 抽象类

huangapple go评论66阅读模式
英文:

Replace switch case: interface vs abstract class

问题

我有一个包含switch语句的代码,想要改进设计。

有接口和抽象类的方式。

我想知道哪种方式更好,以及为什么?

我有以下的类:

enum MovieChargeType {regular, new_release }

class Movie {
public MovieChargeType type;
public double get_price(){
switch (type){
case regular: //返回普通价格
case new_release : // 返回新发布价格 }
}

}

所以我决定用两种方式来改进设计:

1 方式 - 接口

接口 MovieType{
    public double get_price();
}

class RegularMovie implements MovieType{
    public double get_price(){
        // 返回普通价格
    }
}

class NewMovie implements MovieType{
    public double get_price(){
        // 返回新价格
    }
}

class Movie{
        public MovieType type;
        public double get_price(){
              type.get_price();
        } 
    
    }

2 方式 - 抽象类:

抽象类 Movie {
        public MovieChargeType type;
        public abstract double get_price();
    
    }

class RegularMovie extends Movie{
        public double get_price(){
            // 返回普通价格
        }
    }
    
    class NewMovie extends Movie{
        public double get_price(){
            // 返回新价格
        }
    }

我想知道在这种情况下哪种更好?我注意到人们倾向于使用接口,但有人能解释为什么吗?

英文:

I have a code that has a switch statement and want to improve the design.

There's the interface and the the abstract class way.

I want to know which way is better and why ?

I have the following class :

enum MovieChargeType {regular, new_release }

class Movie {
    public MovieChargeType type;
    public double get_price(){
          switch (type){
                  case regular: //return regular price
                  case new_release : // return new_release price }
    } 

}

So I decided to improve the design using 2 ways:

1 Way - Interfaces

Interface MovieType{
    public double get_price();
}

class RegularMovie implements MovieType{
    public double get_price(){
        // return regular price
    }
}

class NewMovie implements MovieType{
    public double get_price(){
        // return new price
    }
}

class Movie{
        public MovieType type;
        public double get_price(){
              type.get_price();
        } 
    
    }

2 Way - abstract classes:

abstract class Movie {
        public MovieChargeType type;
        public abstract double get_price();
    
    }

class RegularMovie extends Movie{
        public double get_price(){
            // return regular price
        }
    }
    
    class NewMovie extends Movie{
        public double get_price(){
            // return new price
        }
    }

I want to know which one is better in such case?
I've noticed that people tend to go with interfaces but can someone explain why?

答案1

得分: 2

> 我想知道在这种情况下哪个更好?我注意到人们倾向于使用接口,但有人能解释一下为什么吗?

继承依赖是所有依赖中最强的,因为您的子类会继承父类的所有依赖关系。例如,如果父类依赖于某个库,只有在类路径上存在该库时,您的子类才能被使用。也许您以前在IDE中曾经遇到过“从类文件间接引用”的错误。这种错误是由于父类的依赖关系未在编译类路径上的情况引起的。

这就是为什么大多数开发者倾向于使用接口并保持接口签名尽可能简单的原因。我的意思是您不应在接口的签名中使用任何库类。只使用POJO(Plain Old Java Objects),这样您的接口只依赖于纯Java,而不依赖于其他库。

抽象类在您想要实现模板方法模式时非常有用。模板方法定义了一个可以由子类扩展的抽象算法。它们只需从父类中覆盖或实现抽象方法。抽象类可以实现行为。因此,如果所有子类都有共同的行为,抽象类可能是一个不错的选择。但要记住,抽象应该是稳定的。如果您的抽象经常发生变化,所有子类都会受到影响。这个问题在每个层次的层级上可能会急剧增加,并使您的代码难以维护。一个很好的规则是,类在层级中越高,它就越稳定。

英文:

> I want to know which one is better in such case? I've noticed that people tend to go with interfaces but can someone explain why?

The inheritance dependency is the strongest of all dependencies, because your sub classes inherit all the dependencies that your parent classes have. E.g. if a parent class depends upon some library your sub class can only be used if that library is on the classpath. Maybe you faced a indirectly referenced from class file error sometime ago in your IDE. This error occures because of dependencies of your parent classes that are not on the compile classpath.

That's why most of the developers tend to use interfaces and keep the interface signature as easy as possible. I mean that you should not use any library classes in an interface's signature. Only use POJOs so that your interfaces only depend on pure Java and not depend upon other libraries.

Abstract classes can be very useful when you want to implement the template method pattern. The template method defines an abstract algorithm that can be extended by sub classes. They just override or implement abstract methods from the parent class. Abstract classes can implement behavior. So if there is a common behavior to all of your sub classes an abstract class might be good choice. But keep in mind that abstractions should be stable. If you have abstractions that change often all of your sub classes are affected. This problem can drammatically increase with each hierarchy level and make your code hard to maintain. A good rule is that the higher a class is in your hierarchy the more stable it must be.

答案2

得分: 1

抽象类允许您定义子类可以覆盖的某些方法的默认行为。接口只允许您定义方法的签名,因此每个实现将是不同的。
如果您希望某些类针对某个价格具有默认行为,则应使用抽象类设计,而不是接口。

英文:

Abstract classes allow you to define the default behaviour of certain methods which the subclasses can override. Interfaces only allow you to define the signature of the methods, so each implementation will be different.
If you would like some classes to have a default behaviour for a price, then use the abstract class design over the interface.

huangapple
  • 本文由 发表于 2020年8月26日 15:36:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63592718.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定