Pregunta

A subtype is established when a class is linked by means of extending or implementing. Subtypes are also used for generics.

How can I differentiate subtyping from subclasses?

¿Fue útil?

Solución

In Java, subclassing is a kind of subtyping.

There are a number of ways Java allows subtyping:

  1. When class A extends B, A is a subtype of B because B b = new A(...); is ok.
  2. When interface A extends B, A is a subtype of B because B b = new A() { ... } is ok.
  3. When class A extends B, A[] is a subtype of B[] because B[] b = new A[0] is ok.
  4. When class A implements B, A is a subtype of B because B b = new A(...) is ok.

It sounds like you want a way to distinguish one from the others. The below should do that.

static boolean isSubclass(Class<?> a, Class<?> b) {
  return !b.isArray() && !b.isInterface() && b.isAssignableFrom(a);
}

It won't handle subtyping of generic classes due to type erasure though. Class instances don't carry type parameters at runtime so there is no way to distinguish the runtime type of a new ArrayList<String>() from a new ArrayList<Integer>().

Otros consejos

Subclass is not the same as subtype. You might create subclasses that are not subtypes. To understand what a subtype is, lets start giving an explanation of what a type is.

When we say that the number 5 is of type integer, we are stating that 5 belongs to a set of possible values (as an example, see the possible values for the Java primitive types). We are also stating that there is a valid set of methods I can perform on the value like addition and subtraction. And finally we are stating that there are a set of properties that are always satisfied, for example, if I add the values 3 and 5, I will get 8 as a result.

To give another example, think about the abstract data types, Set of integers and List of integers, the values they can hold are restricted to integers. They both support a set of methods, like add(newValue) and size(). And they both have different properties (class invariant), Sets does not allow duplicates while List does allow duplicates (of course there are other properties that they both satisfy).

Subtype is also a type, which has a relation to another type, called parent type (or supertype). The subtype must satisfy the features (values, methods and properties) of the parent type. The relation means that in any context where the supertype is expected, it can be substitutable by a subtype, without affecting the behaviour of the execution. Let’s go to see some code to exemplify what I’m saying. Suppose I write a List of integers (in some sort of pseudo language):

class List {
  data = new Array();

  Integer size() {
    return data.length;
  }

  add(Integer anInteger) {
    data[data.length] = anInteger;
  }
}

Then, I write the Set of integers as a subclass of the List of integers:

class Set, inheriting from: List {
  add(Integer anInteger) {
    if (data.notContains(anInteger)) {
      super.add(anInteger);
    }
  }
}

Our Set of integers class is a subclass of List of Integers, but is not a subtype, due to it is not satisfying all the features of the List class. The values, and the signature of the methods are satisfied but the properties are not. The behaviour of the add(Integer) method has been clearly changed, not preserving the properties of the parent type. Think from the point of view of the client of your classes. They might receive a Set of integers where a List of integers is expected. The client might want to add a value and get that value added to the List even if that value already exist in the List. But her wont get that behaviour if the value exists. A big suprise for her!

This is a classic example of an improper use of inheritance. Use composition in this case.

(a fragment from: use inheritance properly).

In general, subclassing means to inherit the attributes of a parent. Subtyping merely means that operations on the supertype can be performed on the subtype. Note that subclassing is a special case of subtyping.

in Java, interfaces represent the structure for describing what behaviors a type can exhibit, which makes it the natural representation for subtyping. Subclassing is manifested in the class hierarchy.

For once, Wikipedia gives a very straight answer to the question:

http://en.wikipedia.org/wiki/Subtype_polymorphism

Subtyping should not be confused with the notion of (class or object) inheritance from object-oriented languages; subtyping is a relation between types (interfaces in object-oriented parlance) whereas inheritance is a relation between implementations stemming from a language feature that allows new objects to be created from existing ones. In a number of object-oriented languages, subtyping is called interface inheritance.

In short, subtyping occurs when you derive an interface (method signatures/access points/ways of reacting to the outside world) from another whereas subclassing occurs when you derive an implementation (methods, attributes/internal state and inside logic) of a class from another class through inheritance.

This terminology is not often used in this way and type usually refers to the data type.

In java, subtyping applies to interfaces, but subclasses does not apply to interfaces.

I don't think Java distinguishes between them? You have only classes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top