Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class 类的实例和表示实例的类之间的差异?_Class_Oop - Fatal编程技术网

Class 类的实例和表示实例的类之间的差异?

Class 类的实例和表示实例的类之间的差异?,class,oop,Class,Oop,我以Java为例,但这更多的是一个与OOP设计相关的一般问题 让我们以Java中的IOExceptions为例。例如,为什么会有类FileNotFoundException?这不应该是IOException的一个实例,其中原因是FileNotFound?我想说FileNotFoundException是IOException的一个实例。这在哪里结束filenotfound但仅检查异常,FileNotFoundNoMatterHowHardITriedException 我也曾在我工作过的项目中看

我以Java为例,但这更多的是一个与OOP设计相关的一般问题

让我们以Java中的
IOException
s为例。例如,为什么会有类
FileNotFoundException
?这不应该是
IOException
的一个实例,其中原因是
FileNotFound
?我想说
FileNotFoundException
IOException
的一个实例。这在哪里结束
filenotfound但仅检查异常
FileNotFoundNoMatterHowHardITriedException

我也曾在我工作过的项目中看到过代码,这些项目中存在着
FirstLineReader
LastLineReader
等类。对我来说,这样的类实际上代表了实例,但我在许多地方看到了这样的设计。例如,看看Spring框架的源代码,它附带了数百个这样的类,每次我看到一个类,我都会看到一个实例,而不是一个蓝图。课程不应该是蓝图吗

我想问的是,如何在这两个非常简单的选项之间做出决定:

备选案文1:

enum DogBreed {
    Bulldog, Poodle;
}

class Dog {
    DogBreed dogBreed;
    public Dog(DogBreed dogBreed) {
        this.dogBreed = dogBreed;
    }
}
备选案文2:

class Dog {}

class Bulldog extends Dog {
}

class Poodle extends Dog {
}
第一个选项为调用方提供了配置其正在创建的实例的要求。在第二个选项中,类已经表示了实例本身(在我看来,这可能是完全错误的…)

如果您同意这些类代表实例而不是蓝图,您会说创建代表实例的类是一种好的做法,还是我看待这个问题的方式完全错误,我的“代表实例的类”只是胡说八道?

首先:我们知道继承的定义,我们可以在SO和internet上找到很多例子。但是,我认为我们应该深入研究,并且更加科学

注0
关于继承和实例术语的澄清。
首先让我为开发生命周期命名开发范围,当我们对系统进行建模和编程时,以及为系统运行时命名运行范围

我们有类和建模,并在开发范围内开发它们。和运行时范围内的对象开发范围中没有对象

在面向对象中,实例的定义是:从类创建对象

另一方面,当我们谈论类和对象时,我们应该澄清我们关于开发范围和运行时范围的观点

因此,通过这篇介绍,我想澄清继承问题:
继承是类之间的关系,而不是对象之间的关系 继承可以存在于开发范围中,而不存在于运行时范围中。运行时作用域中没有继承

在运行我们的项目之后,父类和子类之间没有关系(如果子类和父类之间只有继承)。因此,问题是:什么是
super.invokeMethod1()
super.attribute1
?,它们不是子级和父级之间的关系。父级的所有属性和方法都传输给子级,这只是访问从父级传输的部分的符号

此外,开发范围中没有任何对象。因此,在开发范围内没有任何实例。它只是是-A有-A关系

所以我们说,

我想说
FileNotFoundException
IOException

我们应该澄清我们的范围(开发和运行时)。
例如,如果
FileNotFoundException
IOException
的一个实例,那么运行时特定的
FileNotFoundException
异常(对象)与
FileNotFoundException
之间的关系是什么。它是实例的实例吗

注1
为什么使用继承?继承的目标是扩展父类功能(基于相同类型)

  • 这种扩展可以通过添加新属性或新方法来实现
  • 或重写现有方法
  • 此外,通过扩展父类,我们还可以实现可重用性
  • 我们不能限制父类功能(Liskov原则)
  • 我们应该能够在系统中将孩子替换为家长(Liskov原则)
  • 等等
注2
继承层次结构的宽度和深度
继承的宽度和深度与许多因素有关:

  • 项目:项目的复杂性(类型复杂性)及其架构和设计。项目规模、班级数量等
  • 团队:团队在控制项目复杂性方面的专业知识
  • 等等
然而,我们对此有一些启发。(面向对象设计启发式,Arthur J.Riel)

理论上,继承层次结构应该越深越好

实际上,继承层次结构不应比 一个普通人可以在他或她的短期记忆中保持。流行的 此深度的值为6

注意,它们是启发式的,基于短期记忆数(7)。也许团队的专业知识会影响这个数字。但在许多层次结构中,如组织结构图,都被使用

注3
当我们使用错误的继承时?
基于:

  • 注1:继承的目标(Exte
    Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
    
    enum cause{
        FileNotFound, CharacterCoding, ...;
    }
    
    enum DogBreed {
        Bulldog, Poodle;
    }
    
    class Dog {
        DogBreed dogBreed;
        public Dog(DogBreed dogBreed) {
           this.dogBreed = dogBreed;
        }
    }
    
    interface Dog {
      Breed getBreed();
      Set<Dog> getFavoritePlaymates(DayOfWeek dayOfWeek);
      void emitBarkingSound(double volume);
      Food getFavoriteFood(Instant asOfTime);
    }
    
    abstract class AbstractDog implements Dog {
      private Breed breed;
      Dog(Breed breed) { this.breed = breed; }
      @Override Breed getBreed() { return breed; }
    }
    
    class Poodle extends AbstractDog {
      Poodle() { super(Breed.POODLE); }
      Set<Dog> getFavoritePlaymates(DayOfWeek dayOfWeek) { ... }
      Food getFavoriteFood(Instant asOfTime) { ... }
    }
    
    class Poodle {
        Legs legs;
        Tail tail;
    }
    
    class Bulldog {
        Legs legs;
        Tail tail;
    }