Difference between an instance of a class and a class representing an instance already?

后端 未结 6 2158
别跟我提以往
别跟我提以往 2020-12-30 01:47

I use Java as an example but this is more of a general OOP design related question.

Lets take the IOExceptions in Java as an example. Why is there a cla

6条回答
  •  感情败类
    2020-12-30 02:17

    The first code you cite involves exceptions.

    Inheritance is a natural fit for exception types because the language-provided construct to differentiate exceptions of interest in the try-catch statement is through use of the type system. This means we can easily choose to handle just a more specific type (FileNotFound), or the more general type (IOException).

    Testing a field's value, to see whether to handle an exception, means stepping out of the standard language construct and writing some boiler plate guard code (e.g. test value(s) and rethrow if not interested).

    (Further, exceptions need to be extensible across DLL (compilation) boundaries. When we use enums we may have problems extending the design without modifying the source that introduces (and other that consumes) the enum.)

    When it comes to things other than exceptions, today's wisdom encourages composition over inheritance as this tends to result in less complex and more maintainable designs.

    Your Option 1 is more of a composition example, whereas your Option 2 is clearly an inheritance example.

    If you agree that these classes represent instances instead of blueprints, would you say it is a good practice to create classes that represents instances or is it totally wrong the way I am looking at this and my statement "classes representing instances" is just load of nonsense?

    I agree with you, and would not say this represents good practice. These classes as shown are not particularly customizable and don't represent added value.

    A class that has offers no overrides, no new state, no new methods, is not particularly differentiated from its base. So there is little merit in declaring such a class, unless we seek to do instance-of tests on it (like the exception handling language construct does under the covers). We can't really tell from this example, which is contrived for the purposes of asking the question, whether there is any added value in these subclasses but it doesn't appear so.

    To be clear, though, there are lots of worse example of inheritance, such as when an (pre) occupation like Teacher or Student inherits from Person. This means that a Teacher cannot a be Student at the same time unless we engage in adding even more classes, e.g. TeacherStudent, perhaps using multiple inheritance..

    We might call this class explosion, as sometimes we end up needing a matrix of classes because of inappropriate is-a relationships. (Add one new class, and you need a whole new row or column of exploded classes.)

    Working with a design that suffers class explosion actually creates more work for clients consuming these abstractions, so it is a loose-loose situation.
    Here at issue, is in our trust of natural language because when we say someone is-a Student, this is not, from a logical perspective, the same permanent "is-a"/instance-of relationship (of subclassing), but rather a potentially-temporary role being played that the Person: one of many possible roles a Person might play concurrently at that. In these cases composition is clearly superior to inheritance.

    In your scenario, however, the BullDog is unlikely to be able to be anything other than the BullDog, so the permanent is-a relationship of subclassing holds, and while adding little value, at least this hierarchy does not risk class explosion.

    Note that the main drawback to with the enum approach is that the enum may not be extensible depending on the language you're using. If you need arbitrary extensibility (e.g. by others and without altering your code), you have the choice of using something extensible but more weakly typed, like strings (typos aren't caught, duplicates aren't caught, etc..), or you can use inheritance, as it offers decent extensibility with stronger typing. Exceptions need this kind of extensibility by others without modification and recompilation of the originals and others since they are used across DLL boundaries.

    If you control the enum and can recompile the code as a unit as needed to handle new dog types, then you don't need this extensibility.

提交回复
热议问题