Throw into an abstract class ... how is this possible?

I am really reading a book on design patterns in java and I am newbie :)

http://www.amazon.com/Design-Patterns-Java-TM-Software/dp/0321333020/ in the chapter on the composite template, I came across a code that puzzles me, throws me into an abstract class, I also do not quite understand what happens when an abstract superclass constructor calls the subclass, can you help me!

The listing I'm talking about is in isTree (Set visited)

MachineComponent c = (MachineComponent) i.next(); if (visited.contains(c) || !c.isTree(visited)) 

How can we call the isTree method of a subclass after it is thrown at its abstract superclass and the isTree superclass isTree is abstract?

Here are fragments of two classes:

 package com.oozinoz.machine; /* * Copyright (c) 2001, 2005. Steven J. Metsker. */ import java.util.*; import com.oozinoz.iterator.ComponentIterator; /** * Objects of this class represent either individual machines or composites of * machines. */ public abstract class MachineComponent { /* * Subclasses implement this to support the isTree() algorithm. */ protected abstract boolean isTree(Set s); // rest of class omitted } 

2:

 package com.oozinoz.machine; /* * Copyright (c) 2001, 2005. Steven J. Metsker. */ import java.util.*; import com.oozinoz.iterator.ComponentIterator; import com.oozinoz.iterator.CompositeIterator; /** * Represent a collection of machines: a manufacturing line, a bay, or a * factory. */ public class MachineComposite extends MachineComponent { protected List components = new ArrayList(); /** * @param visited a set of visited nodes * @return true if this composite is a tree * @see MachineComponent#isTree() */ protected boolean isTree(Set visited) { visited.add(this); Iterator i = components.iterator(); while (i.hasNext()) { MachineComponent c = (MachineComponent) i.next(); if (visited.contains(c) || !c.isTree(visited)) return false; } return true; } // rest of class omitted } 
+4
source share
5 answers

This is the difference between the runtime type (the actual type) and the compile time type.

Casting to the abstract MachineComponent class is fine, because the actual instance of the object will actually be some kind of non-abstract subclass of MachineComponent that implements all the abstract methods.

The abstract MachineComponent class is the compile-time type of the assigned variable. But the actual instance (or maybe) is created with this abstract class.

+8
source

isTree is abstract only for an abstract class. Once a class has been initialized as non-abstract, dropping it into abstract will not change its memory. Therefore, a method call in an abstract class effectively calls it in a specific implementation.

The reason this is useful is to pass subclasses through an abstract implementation.

Let's say the String class has a length method. There is no need to have a function for every possible subclass of type String. Instead, you pass the main (abstract) string, which has an implementation of "length", and pass it.

+4
source

OK - try again:

Q: Can you apply an abstract class?

A: Of course - you can

For instance:

 public class UseAbstract { public static void main (String[] args) { // Instantiate an abstract class AbstractPet myDog = new Dog (); myDog.sound (); // Instantiate a concrete class Cat myCat = new Cat (); myCat.sound (); // Cast a concrete class to an abstract class AbstractPet somePet = (AbstractPet)myCat; somePet.sound (); } } abstract class AbstractPet { void sound () { System.out.println ("eek"); } } class Dog extends AbstractPet { void sound () { System.out.println ("Woof"); } } class Cat extends AbstractPet { void sound () { System.out.println ("meow"); } } 
+3
source

Well, take Cat , which is a subclass of the Abstract class Animal .

You can use Cat for Animal because a cat is an animal . He does everything that a normal animal does, since it has the functions of an animal.

Subclassing an abstract class is the same. You can simply use "is a" because it is a subclass.

You can define a list of animals as a zoo, but it can have dogs and cats. After all, they are both animals.

Listing a Cat in Animal doesn't really make it less Cat than it was - you just say that your code processes it as if it would apply to any other animal.

Edit
If you don't like cats (me either), let me redirect you to an article on inheritance . Abstract classes would be useless if you cannot distinguish between them.

+2
source

Q: Can you apply an abstract class?

A: Of course - of course you can.

What you cannot do is call the abstract method of an abstract class. (inset from comments section - Andrew Barber - below). In fact, you are invoking a concrete implementation of this in a subclass.

+1
source

Source: https://habr.com/ru/post/1388862/


All Articles