在我的Java程序中,我有两个非常相似的类,为它们创建一个超类来进行子类化和泛化它们的一些方法会很有意义。
唯一的问题是,其中一个关键字段在一个Queue
中实现,一个在PriorityQueue
中实现。
有没有办法超类化这些并以某种方式推广字段类型并让子类选择它在实例化时可能会做什么?
public Base{
}
public Sub1{
Queue<Customer> customers;
}
public Sub2{
PriorityQueue<Customer> customers;
}
答案 0 :(得分:1)
priorityqueue是抽象队列的一个子类,它实现了队列,所以基本上可以有一个客户队列。
答案 1 :(得分:1)
您需要做的是将customers
的队列作为Base
中的依赖项,并让客户端代码决定实例化哪个队列。
public Base{
private Queue<Customer> customers;
protected Base(Queue<Customer> customers) {
this.queue = queue;
}
}
您不需要Sub1
和Sub2
类,因为它们在使用的队列方面仅与Base
不同。客户端代码可以简单地决定使用哪个队列:
Base baseWithQueue = new Base(new ArrayBlockingQueue<Customer>());
Base baseWithPriorityQueue = new Base(new PriorirityQueue<Customer>());
答案 2 :(得分:1)
def path_foto(instance, filename):
return 'socios_fotos/' + str(instance.num_socio)+'/'
class socio_img (models.Model):
num_socio = models.IntegerField()
foto = models.ImageField(upload_to=path_foto, default='no-photo.jpg')
firma = models.ImageField(upload_to='socios_firmas/', default='no-photo.jpg')
类实现了PriorityQueue
接口,因此我建议将Queue
作为抽象类并保留Base
集合(类型为{{1} }}) 在那里。然后根据需要从customers
或Queue
的构造函数中实例化customers
。
答案 3 :(得分:1)
是的,因为PriorityQueue
实现了Queue
。如果要将创建委托给子类,请让它们传递适当的Queue
以用于基础构造函数:
public class Base {
protected final Queue<Customer> customers;
protected Base(Queue<Customer> c) {
this.customers = c;
}
}
public class Sub1 extends Base {
Sub1() {
super(new WhateverQueue<Customer>());
}
}
public class Sub2 extends Base {
Sub2() {
super(new PriorityQueue<Customer>());
}
}
我应该提一下,如果Sub2
需要在某些PriorityQueue
特定方法中使用特定于Sub2
的方法(例如comparator
),它可以:
播放customers
(因为它知道customers
实际上是PriorityQueue<Customer>
,而不仅仅是Queue<Customer>
),或
声明自己的实例字段,该字段将保留输入的引用:
private PriorityQueue<Customer> priorityCustomers;
Sub2() {
super(new PriorityQueue<Customer>());
this.priorityCustomers = (PriorityQueue<Customer>)(this.customers);
}
#2将所需的强制转换保持在最低限度并且很好地包含在构造函数中,以便以后更容易将PriorityQueue<Customer>
更改为其他内容。
答案 4 :(得分:1)
是的,如果您将字段实现为Queue
,则可以在PriorityQueue
中将该字段实例化为Sub2
,因为PriorityQueue
实现了Queue
(来源) :http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html)
public Base{
Queue<Customer> customers;
public Base(Queue<Customers> queue){
this.customers = queue;
}
}
public Sub1{
public Sub1(){
super(new Queue<Customer>());
}
}
public Sub2{
public Sub2(){
super(new PriorityQueue<Customer>());
}
}
但是,如果您需要在customers
内使用PriorityQueue
字段作为Queue
(而不是Sub2
),则需要将其转换为{ {1}}。
答案 5 :(得分:1)
一种解决方案是为您的customers
属性提供常规Queue
类型,这将为您提供灵活性。但是,如果要在给定的子类中强制执行特定的实现,并在程序的其余部分中携带该信息,则可以使用泛型约束:
public class Base<Q extends Queue<Customers>> {
protected Q customers;
public Base(Q customers) {
this.customers = customers;
}
}
public Sub1 extends Base<Queue<Customers>> {
public Sub1(Queue<String> customers) {
super(customers);
}
}
public Sub2 extends Base<PriorityQueue<Customers>>{
public Sub2() {
// Sub2 only supports PriorityQueues
super(new PriorityQueue<String>());
}
}
这可能很有用,因为它允许您在customers.comparator()
内拨打Sub2
而无需将customers
投射到PriorityQueue
。