我有 2 个类执行非常相似的任务,但需要将不同的数据类型传递给它们才能执行这些功能。
它们最终都写入文件并公开了一个公共方法: write()
使用构造函数进行简单的依赖注入。
这就是它们的不同之处 - 一个类接受特定类型的单个对象,而另一个接受该对象类型的数组。
这是多态性的有效案例吗?我认为可以,但技术上不应该?
如何正确处理这种情况,即 2 个或更多执行非常相似的功能的类,但方式略有不同,关键是需要不同的数据类型作为依赖项传入?
我有 2 个类执行非常相似的任务,但需要将不同的数据类型传递给它们才能执行这些功能。
它们最终都写入文件并公开了一个公共方法: write()
使用构造函数进行简单的依赖注入。
这就是它们的不同之处 - 一个类接受特定类型的单个对象,而另一个接受该对象类型的数组。
这是多态性的有效案例吗?我认为可以,但技术上不应该?
如何正确处理这种情况,即 2 个或更多执行非常相似的功能的类,但方式略有不同,关键是需要不同的数据类型作为依赖项传入?
使用具有通用内容的抽象通用超类。
如果你WriterA
想写一个 type 的参数ArgA
,并且 WriterB
写一个 type 的参数ArgB
,你会做
Writer<T>
包含所有常见内容的摘要,以及一个抽象方法,例如public void write(T arg)
WriterA
延伸Writer<ArgA>
WriterB
延伸Writer<ArgB>
假设你有这个:
class A{
void write(int a){}
}
class B{
void write(int[] a){}
}
既然您说这些方法的实现彼此之间差异很大,那么可变参数可能不是一个合适的选择。为了简化事情,这样做::
class WriteStuff{
void write(int a){}
void write(int[] a){}
}
这将使您的班级获得更高水平的凝聚力。多态性在这里并不是必需的。
话又说回来,信息太少了。您可能应该编写一些示例代码。
在这种情况下,您需要重载方法。一种适用于单个对象,另一种适用于多个对象。他们应该在同一个班级。
下面是一个易于记忆的何时使用什么的方式:
1. 重载是当您需要对不同的数据做同样的事情
时 2. 重载是当您需要以不同的方式对相同的数据
做同样的事情时
public class FileWriter {
public void write(File from){ // single file
// magic logic
}
public void write(File... from){ // multiple files using varargs
// magic logic
}
}
如果您只有两种Write
方法,一种采用单个对象,另一种采用对象列表 -> 我会将这两种方法放在同一个类中。
如果Write
每种类型都有一个,我会选择泛型。
引入基类不是我的首选,最好将一般的东西提取到另一个类中并从不同的类中使用它(has-a 而不是 is-a)。
仅当您具有相同的方法签名但需要以不同的方式做事时,多态性才有用。
如果没有特定的代码示例很难回答,但您提供的场景适合类似于装饰器模式的内容:
class X
{
public void doSomething(int number) { ... }
};
class XForCollections
{
public XForCollections(X x) { ... }
public void doSomething(int[] numbers) { ... }
};
请注意,它不是真正的装饰器,因为XForCollection
它不继承X
.
多态性——意味着给定类型的单个变量能够用于引用不同类型的对象,并自动调用特定于变量引用的对象类型的方法。简而言之,多态是一种自下而上的方法调用。多态性的好处是很容易添加派生对象的新类,而不会破坏 使用多态类或接口的调用代码。当您向对象发送消息时,即使您不知道它是什么特定类型,并且发生了正确的事情,这称为多态性。面向对象编程语言用来实现多态性的过程称为动态绑定。
例子:
启动器
private void init() {
//client or calling code
double dim = 5.0; //i.e. 5 meters radius or width
List<Shape> listShapes = new ArrayList<Shape>(20);
Shape s = new Circle();
listShapes.add(s); //add circle
s = new Square();
listShapes.add(s); //add square
getTotArea (listShapes,dim); //returns 78.5+25.0=103.5
//Later on, if you decide to add a half circle then define
//a HalfCircle class, which extends Circle and then provide an
//area(). method but your called method getTotArea(...) remains
//same.
}
/** called method: method which adds up areas of various
** shapes supplied to it.
**/
public double getTotArea(List<Shape> listShapes, double dim){
Iterator<Shape> it = listShapes.iterator();
double totalArea = 0.0;
//loop through different shapes
while(it.hasNext()) {
Shape s = (Shape) it.next();
totalArea += s.area(dim); //polymorphic method call
}
return totalArea ;
}
}
形状
public abstract class Shape {
protected abstract double area(double dim);
}
正方形
public class Square extends Shape{
@Override
protected double area(double dim) {
return dim*dim;
}
}
圆圈
public class Circle extends Shape{
@Override
protected double area(double dim) {
return Math.PI*dim*dim;
}
}