Inheritance and Defining
Subclasses
Python |
Java |
In an object-oriented
programming language, one can define a new class that reuses code in another
class. The new class becomes a
sublclass of the existing class, which is also called its parent class. The subclass inherits all of the
attributes, including methods and variables, from its parent class and from
any ancestor classes in the hierarchy. Subclassing is a
convenient way to provide extra or more specialized functionality to an
existing resource. For example,
a queue guarantees access to its elements in first-in, first-out order. A priority queue behaves in most
respects just like a queue, except that the higher priority elements are
removed first. If elements have
equal priority, they are removed in standard FIFO order. A priority queue is thus a subclass
of queue, with a specialized method for insertions that guarantees the
appropriate ordering of elements.
The priority queue obtains all of its other methods from the queue
class for free. Here is the definition
of a LinkedQueue class for ordinary queues: class
OneWayNode: def __init__(self, data,
next):
self.data = data
self.next = next class
LinkedQueue: def __init__(self):
self.front = self.rear = None
self.size = 0 def enqueue(self,
element): n
= OneWayNode(element, None)
if self.isEmpty():
self.rear = self.front = n
else:
self.rear.next = n
self.rear = n
self.size += 1 def dequeue(self):
element = self.front.data
self.front = self.front.next
self.size -= 1
if self.isEmpty():
self.rear = None
return element def peek(self):
return self.front.data def isEmpty(self):
return len(self) == 0 def __len__(self):
return self.size The form for defining a
subclass is class
<subclass name>(<parent class name>): <variables and
methods> The LinkedPriorityQueue class is a subclass of LinkedQueue.
The new class includes just two methods, __init__ and enqueue.
The __init__ method in LinkedPriorityQueue simply calls the same method in its parent
class, using the form <parent
class name>.__init__(self) This causes the parent
class to initialize its instance variables. The new enqueue method first checks for an empty queue and if
that is true, calls the enqueue method in the parent class using the form <parent
class name>.<method name>(<args>) Otherwise, the method
searches for the appropriate position of the new element and inserts it
there. Because the front of the
queue is at the head of the linked structure, the search stops when the
incoming element is strictly less than element in the queue. Thus, an incoming element is placed
behind all elements of equal priority. Here is the definition
of LinkedPriorityQueue:
class
LinkedPriorityQueue(LinkedQueue): def __init__(self):
LinkedQueue.__init__(self) def enqueue(self,
element):
if self.isEmpty():
LinkedQueue.enqueue(self, element)
else:
probe = self.front
while probe != None and element >= probe.data:
trailer = probe
probe = probe.next
if probe == None:
# At rear of queue
self.rear.next = OneWayNode(element, None)
self.rear = self.rear.next
elif probe == self.front: # At front of queue
self.front = Node(element, self.front.next)
else:
# Betwixt two nodes
trailer.next = Node(element, probe)
self.size += 1 |
In an object-oriented
programming language, one can define a new class that reuses code in another
class. The new class becomes a
sublclass of the existing class, which is also called its parent class. The subclass inherits all of the
attributes, including methods and variables, provided they are specified as public or protected, from its parent class and from any ancestor
classes in the hierarchy. Subclassing is a
convenient way to provide extra or more specialized functionality to an
existing resource. For example,
a queue guarantees access to its elements in first-in, first-out order. A priority queue behaves in most
respects just like a queue, except that the higher priority elements are
removed first. If elements have
equal priority, they are removed in standard FIFO order. A priority queue is thus a subclass
of queue, with a specialized method for insertions that guarantees the
appropriate ordering of elements.
The priority queue obtains all of its other methods from the queue
class for free. The LinkedQueue class makes its instance variables visible to
subclasses but not to others by declaring them as protected.
Likewise, the inner OneWayNode class and its attributes are also defined as protected. Here is the definition
of a LinkedQueue class for ordinary queues: import
java.util.*; public class
LinkedQueue<E> implements TrueQueue<E>{ protected
OneWayNode<E> front, rear; Protected int size; public LinkedQueue(){ this.front =
this.rear = null; this.size =
0; } public void enqueue(E
element){
OneWayNode<E> n = OneWayNode<E>(element, null);
if (this.isEmpty())
this.rear = this.front = n;
else{
this.rear.next = n;
this.rear = n; }
this.size += 1; } public E dequeue(){ E
element = this.front.data;
this.front = this.front.next;
this.size -= 1;
if (this.isEmpty())
this.rear = null;
return element; } public E peek(){; return
this.front.data; } public boolean isEmpty(){ return
this.size() == 0; } public int size(){ return
this.size == 0; } protected class
OneWayNode<E>{
protected E data;
protected OneWayNode<E> next;
protected OneWayNode(E data, OneWayNode next){
this.data = data;
this.next = next; } } } The form for defining a
subclass is public class
<subclass name> extends <parent class name>{ <variables and
methods> } The LinkedPriorityQueue class is a subclass of LinkedQueue.
The new class includes a constructor and the enqueue method.
The constructor in LinkedPriorityQueue is optional, but explicitly calls the
constructor in its parent class, using the statement super(); This causes the parent
class to initialize its instance variables. The new enqueue method first checks for an empty queue and if
that is true, calls the enqueue method in the parent class using the form super.<method
name>(<args>) Otherwise, the method
searches for the appropriate position of the new element and inserts it
there. Because the front of the
queue is at the head of the linked structure, the search stops only when the
incoming element is strictly less than element in the queue. Thus, an incoming element is placed
behind all elements of equal priority.
Elements in a priority
queue must be comparable.
Therefore, the element type of the LinkedPriorityQueue class is specified as Comparable.
The syntax for relating the element types of LinkedPriorityQueue and LinkedQueue in the class header is a bit tricky, but gets
the job done. Here is the definition
of LinkedPriorityQueue:
import
java.util.*; public class
LinkedPriorityQueue<E extends Comparable>
extends LinkedQueue<E>{ public
LinkedPriorityQueue(){
super(); } public void enqueue(E
element){ if
(this.isEmpty())
super.enqueue(element);
else{
OneWayNode<E> probe = this.front;
OneWayNode<E> trailer = null;
while (true){
if (probe == null || element.compareTo(probe.data)
< 0)
break;
trailer = probe;
probe = probe.next;
}
if (probe == null)
# At rear of queue
this.rear.next = new OneWayNode<E>(element, null);
this.rear = this.rear.next;
else if (probe == this.front) # At front of queue
this.front = new OneWayNode<E>(element, this.front.next);
else
#
Betwixt two nodes
trailer.next = new OneWayNode<E>(element, probe);
this.size += 1; } } } |