我正在学习 java 并且想知道在什么情况下你会想要扩展一个像这里这样的类:
http://5upcodes.blogspot.fi/2013/08/java-inheritance.html
谢谢!
我正在学习 java 并且想知道在什么情况下你会想要扩展一个像这里这样的类:
http://5upcodes.blogspot.fi/2013/08/java-inheritance.html
谢谢!
我最喜欢的继承示例是形状示例。所有正方形都是形状,但并非所有形状都是正方形。
假设您有一个名为“shape”的类。所有形状都有周长、面积等。这些将是形状类的数据成员。
假设您想创建一个名为 circle 的类。circle 可以扩展您的 shape 类,以便它仍然具有 shape 类的数据成员,并且您可以添加特定于圆的元素,例如半径。(正方形没有半径)。
circle 类可以说是从 shape 类“继承”,因为它具有 shape 的所有特征,以及特定于 circle 类的新特征。
当您想创建一个通常类似于超类(被扩展的类)的类时,您可以扩展它并自定义它。覆盖它的一些功能,和/或添加功能。
这是一个“is-a”场景,是 OOP 的三大支柱(继承、封装、多态)之一。如果你有一个 Animal 类,那么你可能想从 Animal 扩展一个 Dog 类。狗是一种动物,但反之则不然。所有动物都有细胞,但除此之外,狗还有其他特征。这将是一个非常基本的想法。
出于简单的原因,我们将一个类扩展为另一个类,并且基础称为继承。
比如说,如果你想创建一个程序,其中有两个车辆类,即 Car 和 Boat,除了一些之外,它们具有相似的属性。
public class Vehicle
{
void engine()
}
protected class Car extends Vehicle
{
void tyres()
}
protected class Boat extends Vehicle
{
void propeller()
}
您会看到两辆车都有发动机,但有不同的模式,一辆在轮胎的帮助下移动,另一辆在螺旋桨的帮助下移动。
所以,两个避免重写方法引擎的代码,我们在子类中继承它。希望,这会帮助你!
OOP 的良好做法是program towards interfaces
. 但是在某些情况下,您可以利用继承:例如,当您的顶级类具有明确定义的行为(我的意思是具体代码)时,所有子类都将继承该行为 - 这可以减少代码、复杂性并为您提供更好的维护设想。
另一方面,如果你的模型过于抽象(基本行为不是很清楚),那么你应该考虑使用接口。
如果您正在创建现实生活中的软件,请不要忘记设计模式- 有人可能已经解决了您的问题。
扩展类和接口一样是 OOP 的基础之一。可以说,您有一个名为 Building 的通用类。它具有区域,建筑物所在的城市(或坐标)等成员。
现在,通过扩展,您可以将房屋指定为“Cottage”、“SkyScraper”等。它们将具有父级功能+更多功能(例如 SkyScraper 的级别数)。
使用继承的主要原因是扩展基类的行为。
例如,如果您正在制作视频游戏,您可能有一个Character
类,其中包含角色导航世界和执行其他操作所需的所有代码。
然后,您可以Character
使用Player
and进行扩展NPC
,以便Player
(表示玩家角色)包含允许玩游戏的人控制其角色的逻辑,并且NPC
(表示非玩家角色)包含允许计算机控制其他人的逻辑人物。这样,每个字符的所有逻辑核心都封装在Character
类中,子类只有扩展特定行为所需的逻辑。
例如,Character
该类可能有一个移动方法。
protected void MoveToLocation(x, y)
{
//movement logic goes here
}
然后Player
该类可能包含一个 mouselistener 以将播放器移动到单击的任何位置。
public void mouseClicked (MouseEvent mouseEvent)
{
MoveToLocation(mouseEvent.getX(), mouseEvent.getY());
}
并且NPC
会以某种方式自行解决
protected void decideWhereToGo()
{
int destinationX, destinationY;
//logic for determining destination
MoveToLocation(destinationX, destinationY);
}
因为他们都继承自Character
他们都知道如何MoveToLocation
,如果你想改变它是如何完成的,你只需要在一个地方修改代码并且每个Character
(无论它们是 aPlayer
还是NPC
它们仍然是Character
通过继承的方式)将有更新的行为。
当您扩展一个类时,您在原始类和新扩展类之间存在父子关系。
子类,继承父类的子类,将拥有父类的每个成员,无需再次声明它们。即使是私人成员,尽管您将无法直接访问它们。
当您希望新类具有原始类的所有相同功能时,您可以扩展一个类,甚至更多。然后子类可以添加新功能,或者覆盖父类的某些功能。
当您希望拥有一组相关并共享一些通用功能但在细节方面具有不同实现的类时,您也可以使用扩展。例如,通常对于图形界面,您有一个Control
类,它具有与渲染和定位相关的功能。然后你有它的孩子叫Button
,Textbox
等等Combo
。它们都有一些共同的实现,但每个细节都不同。
确保也学习接口。有时您需要很多相关的类,以便它们具有一组共同的成员,但没有共享的功能。在这种情况下,实现接口可能比扩展通用类更好。接口就像一个类,但没有实现(它只是告诉你它的实现者应该有哪些成员)。
通常扩展一个类是为了让你基于某些东西创建类。例如,为了创建一个活动,您必须扩展活动。如果您的类要设置 IntentService,那么您必须扩展您的类以使用 IntentService。
public class AClassNameHere extends Activity implements OnClickListener {
public class ClassName extends IntentService{
您可以将超类扩展为覆盖超类方法以特定于子类示例:
如果您的超类是具有泛型行为的泛型类,例如 Animal 类可以是泛型类,例如
class Animal{
private String name;
public String getVoice(){
return "Animal";
}
}
现在你需要创建一个 Cat 类,它是 Animal 类型,但声音不同,然后你只需扩展超类 Animal 并重写 getVoice() 方法,如
class Cat extends Animal{
public String getVoice(){
return "mew";
}
}
现在如果你有这样的代码: Animal cat= new Cat(); cat.getVoice();//它会返回 "mew"
实际上,您可以在多种情况下使用它,例如 1. 将现有框架类扩展到您的自定义类。2. 如果您正在开发任何框架,您可以公开一些您希望用户自定义的类。
但是覆盖引入了 IS-A 关系。
继承存在三个主要缺点。即使关系是“是”关系,在决定继承一个类时也要考虑这三个。
几乎从不。最好只扩展为它积极设计的类。大多数类的实现者没有考虑如果人们扩展他们的类会发生什么。有各种各样的问题。
作曲是你最好的朋友。
漏洞包括
Josh Bloch 在其出色的《Effective Java, 2nd Edition》一书中多处讨论了这一点,包括第 8、16 和 17 条。