简体   繁体   English

Java继承层次结构

[英]Java Inheritance hierarchy

Rectangle is Parent class and Square is the child class of rectangle(Parent). 矩形是父类,而正方形是矩形(父类)的子类。 Is this relationship correct? 这种关系正确吗?

It is obvious that square is more specific in front of rectangle and it can be put in a IS-A relationship with rectangle. 显然,正方形在矩形的前面更具体,可以将其与矩形建立IS-A关系。 But if we see in this way the memory utilization will be more( while creating the object of square in heap both instance variables length and breath will be allocated memory separately like rectangle). 但是,如果我们以这种方式看到内存使用率会更高(在堆中创建正方形对象时,实例变量length和breath会像矩形一样分别分配内存)。

Whereas we can reduce it to half by declaring only one variable in Square class by putting square in parallel to rectangle. 而我们可以通过将Square与矩形平行放置来声明Square类中的一个变量,从而将其减少一半。 So while creating the object of square in heap only one instance variable will be allocated memory. 因此,在堆中创建Square对象时,只会分配一个实例变量内存。

So which approach will be more efficient? 那么哪种方法会更有效?

  1. By putting Square as a child of rectangle. 通过将Square作为矩形的子级。

     Or 
  2. By Putting Square at a parallel branch in inheritance hierarchy in view of effective heap memory utilization? 鉴于有效的堆内存利用率,通过将Square放在继承层次结构中的并行分支上?

Please correct me if I am wrong at any point.. 如果我在任何时候错了,请纠正我。

Inheritance is best used to express an "is a" relationship between objects. 继承最适合用来表示对象之间的“是”关系。

Here is a bad use of inheritance just for example: 例如,这是继承的一种错误用法:

public class List<E> {
    :
}

public class Vector<E> extends List<E> {
    :
}

You might ask, "if Vector uses all the functionality of List, then why is this a bad example of inheritance?" 您可能会问:“如果Vector使用了List的所有功能,那么为什么这是一个不好的继承示例?” This is suboptimal because a Vector isn't a List. 这是次优的,因为Vector不是列表。 One consequence might be that the List class could evolve in a way that was not important to Vectors or, worse, which creates security vulnerabilities or flaws in Vectors. 结果可能是List类可能以对Vectors不重要的方式演化,或者更糟的是,它会在Vectors中创建安全漏洞或缺陷。 In a situation such as this, composition would be much better, ie a Vector "has a" List (rather than forcing a Vector to be a List). 在这种情况下,组合会更好,即,向量“具有”列表(而不是强迫向量成为列表)。

A child class really should be an example of its parent (eg. A MountainBike is a Bicycle). 子类别确实应该是其父类别的示例(例如,MountainBike是自行车)。 If it isn't then it is quite probably true that the relationship is not one which should be expressed by an inheritance hierarchy. 如果不是这样,则很可能关系不是应该由继承层次结构表示的关系。

But if we see in this way the memory utilization will be more( while creating the object of square in heap both instance variables length and breath will be allocated memory separately like rectangle 但是如果以这种方式看到内存使用率会更高(在堆中创建正方形对象时,实例变量的长度和呼吸将分别分配给内存,例如矩形

Hierarchies are a tool to encourage code reuse and improve modularity. 层次结构是鼓励代码重用和改善模块化的工具。 If, at this stage of a project, you are worried about memory allocation then you should choose a different language than Java. 如果在项目的此阶段担心内存分配,则应该选择与Java不同的语言。 You use Java because you want to gain the design improvements related to abstraction and object orientation. 使用Java 是因为您希望获得与抽象和面向对象有关的设计改进。

You can't be sure that is-a approach to design is obvious choice here. 您不能肯定这is-a设计方法在这里是显而易见的选择。 You could instead have a Rectangle as base and it will be a square when the width equals height. 相反,您可以将Rectangle作为基础,并且当宽度等于高度时它将是一个正方形。 Although a Square is-a Rectangle, you can model it as with Rectangle attributes too. 尽管Square 是一个 Rectangle,但您也可以使用Rectangle属性对其进行建模。

But I agree that conceptually it would seem better to model a Square as extending a Rectangle . 但我同意,从概念上讲,将Square建模为扩展Rectangle似乎更好。

Your question about reducing space complexity 您关于减少空间复杂性的问题

This hierarchy is simple right now so you are asking that question but suppose you are building Rectangle with operations that take both width and height. 这个层次结构现在很简单,因此您在问这个问题,但是假设您正在使用同时包含宽度和高度的操作来构建Rectangle These operations will also be valid to a Square . 这些操作也将对Square有效。 Ex: 例如:

public int calculateArea(int width, int height);

You will likely use the same method if you are extending Square from a Rectangle . 如果从Rectangle扩展Square ,则可能会使用相同的方法。 Now, to perform this operation, you have to initialize the width and height through a constructor. 现在,要执行此操作,您必须通过构造函数初始化宽度高度 All you do is set these to be the same and you can get the area. 您要做的就是将这些设置为相同,然后您可以得到该区域。 You don't have to override it for any reason. 您不必出于任何原因而覆盖它。 But if Square is separate then how will you have the area calculation behavior? 但是,如果Square是分开的,那么您将如何进行面积计算? Would you have it as separately inserted just for the space complexity agnostic design considerations. 您是否仅出于空间复杂性不可知的设计考虑而将它单独插入。

Everything that is built around width and height can be equally leveraged by a Square if you extend it. 如果扩展正方形,围绕宽度高度构建的所有内容都可以被正方形同样利用。

The space saving approach you suggested discards the reusability of your code. 您建议的节省空间的方法放弃了代码的可重用性。 That's why, it is preferable to extend Square rather than saving that memory. 因此,最好扩展Square而不是节省该内存。

So which approach will be more efficient? 那么哪种方法会更有效?

 By putting Square as a child of rectangle. Or By Putting Square at a parallel branch in inheritance hierarchy in view of effective heap memory utilization? 

Your efficiency comes at a big price of losing code re-usability. 效率的提高是以牺牲代码的可重用性为代价的。 So, answer is, " By putting Square as a child of rectangle. " 因此,答案是“ 通过将Square作为矩形的子代。

But wait...You may be able to save memory too! 但是,请稍等...您也许也可以节省内存!

If both the width and height are not primitives then references like Width and Height can be made to point to the same object instead of 2 different ones. 如果width和height都不是基元,则可以使Width和Height之类的引用指向同一对象,而不是2个不同的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM