【发布时间】:2013-10-19 15:08:06
【问题描述】:
我是一个 Java 菜鸟,如果问题太简单或太复杂,请原谅我,但我一直在阅读我的 Java 书籍,在第一章中我们介绍了继承,后来我们谈到了接口。
我的问题是: 什么时候使用接口合适,什么时候覆盖方法合适?
既然我们已经有了覆盖功能,为什么还需要接口?
【问题讨论】:
-
您无法使用接口和覆盖方法进行比较。这是两个不同的东西
标签: java inheritance
我是一个 Java 菜鸟,如果问题太简单或太复杂,请原谅我,但我一直在阅读我的 Java 书籍,在第一章中我们介绍了继承,后来我们谈到了接口。
我的问题是: 什么时候使用接口合适,什么时候覆盖方法合适?
既然我们已经有了覆盖功能,为什么还需要接口?
【问题讨论】:
标签: java inheritance
看看这个页面:http://www.javaworld.com/javaworld/javaqa/2001-04/03-qa-0420-abstract.html。它解释了一些差异,以及何时应该使用它们。
或者这个:http://www.javabeginner.com/learn-java/java-abstract-class-and-interface。我觉得这个更好。
【讨论】:
可以这样想:考虑一个 Car 类,作为 Pickup、MiniVan 和 SUV 等多个类的基础,您可以在其中覆盖 Car 方法。
到目前为止,一切都很好。
但就像在现实生活中一样,汽车不仅仅是汽车。例如,它也是一个身体。因此,根据您的应用程序,您需要将飞机、汽车以及其他一些东西视为物理实体,它们都有一些共同点,例如:
double getMass();
double getVelocity();
同时,汽车不仅是实体,还是家庭资产。例如,它可能与贷款相关联。因此,您可能希望支持以下方法:
Loan getLoan();
因此,接口可以用来为不同类的对象提供某些视图,就好像这些对象具有相同的类型一样。
【讨论】:
接口提供了类应该实现的某种契约。
假设您有一个名为Car 的接口,它有一个accelerate() 方法。这里没有实现。
现在,您想要Car 的一些实际用法,因此您创建了一个SubaruCar 类,该类实现 accelerate() 方法。
现在,例如,如果您需要一个 SubaruImpreza 类,它可能会使用继承和关键字 extends 扩展 SportCar。在这个类中,你覆盖 accelerate() 方法(因为它会比通常的SubaruCar 加速得更快)
【讨论】:
网上满是关于这个问题的文档,但如果我尝试用简单的英语对其进行总结,那么:
界面 - 这就像一份合同,上面写着“我可以提供此功能”。
接口示例:Comparable 表示任何可比较的对象都可以提供比较功能
Overreid - 当您使用 inharitance 并希望某些功能对子类采取不同的行为时。
这是两个不同的问题,一开始可能会令人困惑
【讨论】:
这里的其他人提出了很好的观点,但让我提供一个稍微不同的观点。
如果您有在对象中常见的行为(不是代码或特征,而是实际行为),请考虑在方法中具有一些已建立行为的抽象类(可能声明为final)。但小心点。查看Circle-Ellipse problem 以了解为什么 Circle 可能不应该从 Ellipse 继承,尽管这似乎很明显。
你只能扩展一个类,所以让它成为一个好的类。请记住,好的软件设计是尽可能松散地耦合您的代码。换句话说,尽可能确保更改一个类中的代码不涉及更改一堆其他类中的代码。这就是为什么周末加班的原因。 没有比继承更紧密的耦合,所以要明智地选择。向基类添加新行为意味着每个派生类也会获得它,这可能会导致很多尴尬的问题(例如,通过实现一个空方法来满足约定)。
最后,扩展多个接口的能力允许客户端代码根据不同的 API 协定以不同的方式处理对象,因此我可以在代码的一部分中将 Person 对象视为 Doctor 和 @987654325 @ 在代码的另一部分。但不要搞错,这不是多重继承。
最后,这取决于您的领域、更改基类的可能性以及您将学会用经验衡量的其他因素。不过,在所有条件相同的情况下,更喜欢接口而不是继承。
等到你学习了 Ruby 和 Scala,你就可以了解模块和特征。然后它变得非常有趣。
希望对您有所帮助。
【讨论】: