给出基类 Base ,即 A , B , C 扩展 Base < / em>。 如果只有 C 中存在特定方法 m()。要调用 m(),您应该首先确定给定的类是否为 C 的类型,一种方法是使用:
Dim myArray(0 To 4) As String
但是我想使用:
otherMethod(Base b){
if(b instanceof C)
b.m();
}
这意味着我必须将 m()方法拉到超类 Base 上,并且只能在类 C 中实现。但是 m()与 A 和 B 类没有关系,因此不属于它们。这对于代码可读性而言并不直观。那么,对于这种情况,是否有一种更好的设计来使用多态性而又没有不合理的方法位置?
答案 0 :(得分:0)
如果类C
具有任何特定方法,则该类不应成为Base
类的一部分。要调用方法m()
,您将必须使用instanceof
运算符检查实例的类型,然后将Base
类转换为C
,然后调用方法{{1} }如下
m()
此外,正如其他人已经引用了otherMethod(Base base){
If(base instanceof C){
C c= (C) base;
c.m();
}
}
和Collection
的示例一样,如果您的类List
需要特定的方法,则应创建一个C
,可以说它叫interface
,它应该扩展Child
接口。其他2个类应实现Base
接口。类Base
应该实现C
接口。
现在,当您设计Child
接口时,肯定不会知道其他类可以实现哪些特定方法。因此,您也不应在otherMethod中调用任何特定的方法。
答案 1 :(得分:0)
该问题的答案可能会对您有所帮助:Is there a solution to empty methods in subclass?
基本上,它建议您在超类中创建一个空方法,然后根据需要在子类中实现它。但是,它确实警告说这种做法应该是例外,而不是规则,因此使用“ instanceof”实际上可能是更实际的解决方案。
答案 2 :(得分:0)
另一个选择是使用覆盖方法。在Base对象上调用otherMethod()时,它将调用Base中定义的doThings(),除非它是C的实例,该实例已使doThings()重载。
public class Base {
public void doThings() {
// nothing happens
}
public void otherMethod() {
doThings(); // will call method above if instance is Base object, will call method below if C object
}
}
class C extends Base {
public void doThings() {
System.out.println( "Things actually get done" );
}
}
答案 3 :(得分:0)
如果您使用Java 8,而性能不是问题(如果要以60fps渲染10000个形状,则会出现这种情况),然后过滤集合。
假设一个Collection<Shape> shapes
:
shapes.stream()
.filter(s -> s instanceof C)
.forEach(c -> ((C)c).m());
nb。您永远不要在与行为无关的类或接口中声明行为(即方法)。在ernest_k的示例中,不要仅仅因为get(int)
使用Collection
来将List
放在接口Collection<A> justA;
Collection<B> justB;
Collection<C> justC;
中。这样可以使类结构保持整洁和易于理解。相反,可以通过困难的方式(使用类型检查和强制转换)或通过将不同的子类分离到不同的集合中(从而不必检查类型)来更改类结构的用法。
如果您有这个:
D
那么您就不会遇到这个问题,但是您会遇到另一个(可能更糟)的问题,即每次添加另一个子类(例如<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<div>
<div class="row justify-content-center text-center">
<div class="btnWrap col-12 col-md-6 col-lg" style="">
<button type="button" id="TopNames" class="btn btn-secondary btn-top active" onclick="topButtonClick(this)">Najpogostejša imena</button>
</div>
<div class="btnWrap col-12 col-md-6 col-lg" style="">
<button type="button" id="TopBabyNames" class="btn btn-secondary btn-top" onclick="topButtonClick(this)">Imena novorojenčkov</button>
</div>
<div class="btnWrap col-12 col-md-4 col-lg" style="">
<button type="button" id="TopDisappearingNames" class="btn btn-secondary btn-top" onclick="topButtonClick(this)">Izginjajoča imena</button>
</div>
<div class="btnWrap col-12 col-md-4 col-lg" style="">
<button type="button" id="TopModernNames" class="btn btn-secondary btn-top" onclick="topButtonClick(this)">Sodobna imena</button>
</div>
<div class="btnWrap col-12 col-md-4 col-lg" style="">
<button type="button" id="TopLastnames" class="btn btn-secondary btn-top" onclick="topButtonClick(this)">Najpogostejši priimki</button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
)时,您都必须在各处更改代码,并且您可能会忘记在某个地方进行更改。
答案 4 :(得分:0)
除了添加$("#companies_table").html("#{escape_javascript(render 'business/companies/partials/companies_table')}");
$("tr[data-link]").click(function() {
window.location = $(this).data("link");
})
Base.visit(IVisitor v) {v.visit(this);}
然后编写所需的IVisitor(此处带有C的实例) 当然,您可以只使用Consumer而不是自己的访问者界面。我只是想说清楚。