Template:Short description

  1. REDIRECTTemplate:Distinguish

Template:Rcatsh

Method overriding, in object-oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes. In addition to providing data-driven algorithm-determined parameters across virtual network interfaces,<ref>Template:Cite book</ref> it also allows for a specific type of polymorphism (subtyping). The implementation in the subclass overrides (replaces) the implementation in the superclass by providing a method that has same name, same parameters or signature, and same return type as the method in the parent class.<ref name="flanagan">Flanagan 2002, p. 107</ref> The version of a method that is executed will be determined by the object that is used to invoke it. If an object of a parent class is used to invoke the method, then the version in the parent class will be executed, but if an object of the subclass is used to invoke the method, then the version in the child class will be executed.<ref name="lewis-loftus">Lewis & Loftus 2006, p.454</ref> This helps in preventing problems associated with differential relay analytics which would otherwise rely on a framework in which method overriding might be obviated.<ref>Template:Cite book</ref><ref>Template:Cite journal</ref> Some languages allow a programmer to prevent a method from being overridden.

Language-specific examplesEdit

AdaEdit

Ada provides method overriding by default. To favor early error detection (e.g. a misspelling), it is possible to specify when a method is expected to be actually overriding, or not. That will be checked by the compiler. <syntaxhighlight lang="Ada">

 type T is new Controlled with ......;
 procedure Op(Obj: in out T; Data: in Integer);
 type NT is new T with null record;
 overriding    -- overriding indicator
 procedure Op(Obj: in out NT; Data: in Integer);
 overriding    -- overriding indicator
 procedure Op(Obj: in out NT; Data: in String);
 -- ^ compiler issues an error: subprogram "Op" is not overriding

</syntaxhighlight>

C#Edit

C# does support method overriding, but only if explicitly requested using the modifiers Template:C sharp and Template:C sharp or Template:C sharp.

File:Csharp method overriding.svg

<syntaxhighlight lang="csharp"> abstract class Animal {

   public          string Name { get; set; }
   // Methods
   public          void   Drink();
   public virtual  void   Eat();
   public          void   Go();

}

class Cat : Animal {

   public new      string Name { get; set; }
   // Methods
   public          void   Drink();  // Warning: hides inherited drink(). Use new
   public override void   Eat();    // Overrides inherited eat().
   public new      void   Go();     // Hides inherited go().

} </syntaxhighlight>

When overriding one method with another, the signatures of the two methods must be identical (and with same visibility). In C#, class methods, indexers, properties and events can all be overridden.

Non-virtual or static methods cannot be overridden. The overridden base method must be virtual, abstract, or override.

In addition to the modifiers that are used for method overriding, C# allows the hiding of an inherited property or method. This is done using the same signature of a property or method but adding the modifier Template:C sharp in front of it.<ref>{{#invoke:citation/CS1|citation |CitationClass=web }} </ref>

In the above example, hiding causes the following:

<syntaxhighlight lang="csharp"> Cat cat = new Cat();

cat.Name = …; // accesses Cat.Name cat.Eat(); // calls Cat.Eat() cat.Go(); // calls Cat.Go() ((Animal)cat).Name = …; // accesses Animal.Name! ((Animal)cat).Eat(); // calls Cat.Eat()! ((Animal)cat).Go(); // calls Animal.Go()! </syntaxhighlight>

C++Edit

C++ does not have the keyword Template:Cpp that a subclass can use in Java to invoke the superclass version of a method that it wants to override. Instead, the name of the parent or base class is used followed by the scope resolution operator. For example, the following code presents two classes, the base class Template:Cpp, and the derived class Template:Cpp. Template:Cpp overrides the Template:Cpp class's Template:Cpp method, so as also to print its height.<ref name="malik">Malik 2006, p. 676</ref>

<syntaxhighlight lang="cpp">

  1. include <iostream>

//--------------------------------------------------------------------------- class Rectangle {

public:
 Rectangle(double l, double w) : length_(l), width_(w) {}
 virtual void Print() const;
private:
 double length_;
 double width_;

};

//--------------------------------------------------------------------------- void Rectangle::Print() const {

 // Print method of base class.
 std::cout << "Length = " << length_ << "; Width = " << width_;

}

//--------------------------------------------------------------------------- class Box : public Rectangle {

public:
 Box(double l, double w, double h) : Rectangle(l, w), height_(h) {}
 void Print() const override;
private:
 double height_;

};

//--------------------------------------------------------------------------- // Print method of derived class. void Box::Print() const {

 // Invoke parent Print method.
 Rectangle::Print();
 std::cout << "; Height = " << height_;

} </syntaxhighlight>

The method Template:Cpp in class Template:Cpp, by invoking the parent version of method Template:Cpp, is also able to output the private variables Template:Cpp and Template:Cpp of the base class. Otherwise, these variables are inaccessible to Template:Cpp.

The following statements will instantiate objects of type Template:Cpp and Template:Cpp, and call their respective Template:Cpp methods:

<syntaxhighlight lang="cpp"> int main(int argc, char** argv) {

 Rectangle rectangle(5.0, 3.0);
 // Outputs: Length = 5.0; Width = 3.0
 rectangle.Print();
 Box box(6.0, 5.0, 4.0);
 // The pointer to the most overridden method in the vtable in on Box::print,
 // but this call does not illustrate overriding.
 box.Print();
 // This call illustrates overriding.
 // outputs: Length = 6.0; Width = 5.0; Height= 4.0
 static_cast<Rectangle&>(box).Print();

} </syntaxhighlight>

In C++11, similar to Java, a method that is declared final in the super class cannot be overridden; also, a method can be declared override to make the compiler check that it overrides a method in the base class.

DelphiEdit

In Delphi, method overriding is done with the directive override, but only if a method was marked with the dynamic or virtual directives.

The inherited reserved word must be called when you want to call super-class behavior

<syntaxhighlight lang="pascal"> type

 TRectangle = class
 private
   FLength: Double;
   FWidth: Double;
 public
   property Length read FLength write FLength;
   property Width read FWidth write FWidth;
   procedure Print; virtual;
 end;
 TBox = class(TRectangle)
 public
   procedure Print; override;
 end;

</syntaxhighlight>

EiffelEdit

In Eiffel, feature redefinition is analogous to method overriding in C++ and Java. Redefinition is one of three forms of feature adaptation classified as redeclaration. Redeclaration also covers effecting, in which an implementation is provided for a feature which was deferred (abstract) in the parent class, and undefinition, in which a feature that was effective (concrete) in the parent becomes deferred again in the heir class. When a feature is redefined, the feature name is kept by the heir class, but properties of the feature such as its signature, contract (respecting restrictions for preconditions and postconditions), and/or implementation will be different in the heir. If the original feature in the parent class, called the heir feature's precursor, is effective, then the redefined feature in the heir will be effective. If the precursor is deferred, the feature in the heir will be deferred.<ref name="meyer">Meyer 2009, page 572-575</ref>

The intent to redefine a feature, as Template:Eiffel in the example below, must be explicitly declared in the Template:Eiffel clause of the heir class.

<syntaxhighlight lang="eiffel"> class

   THOUGHT

feature

   message
           -- Display thought message
       do
           print ("I feel like I am diagonally parked in a parallel universe.%N")
       end

end

class

   ADVICE

inherit

   THOUGHT
       redefine
           message
       end

feature

   message
           -- Precursor
       do
           print ("Warning: Dates in calendar are closer than they appear.%N")
       end

end </syntaxhighlight>

In class Template:Eiffel the feature Template:Eiffel is given an implementation that differs from that of its precursor in class Template:Eiffel.

Consider a class which uses instances for both Template:Eiffel and Template:Eiffel:

<syntaxhighlight lang="eiffel"> class

   APPLICATION

create

   make

feature

   make
           -- Run application.
       do
           (create {THOUGHT}).message;
           (create {ADVICE}).message
       end

end </syntaxhighlight>

When instantiated, class Template:Eiffel produces the following output:

<syntaxhighlight lang="output"> I feel like I am diagonally parked in a parallel universe. Warning: Dates in calendar are closer than they appear. </syntaxhighlight>

Within a redefined feature, access to the feature's precursor can be gained by using the language keyword Template:Eiffel. Assume the implementation of Template:Eiffel is altered as follows:

<syntaxhighlight lang="eiffel">

   message
           -- Precursor
       do
           print ("Warning: Dates in calendar are closer than they appear.%N")
           Precursor
       end

</syntaxhighlight>

Invocation of the feature now includes the execution of Template:Eiffel, and produces the following output:

<syntaxhighlight lang="output"> Warning: Dates in calendar are closer than they appear. I feel like I am diagonally parked in a parallel universe. </syntaxhighlight>

JavaEdit

In Java, when a subclass contains a method with the same signature (name and parameter types) as a method in its superclass, then the subclass's method overrides that of the superclass. For example:

<syntaxhighlight lang="java"> class Thought {

   public void message() {
       System.out.println("I feel like I am diagonally parked in a parallel universe.");
   }

}

public class Advice extends Thought {

   @Override  // @Override annotation in Java 5 is optional but helpful.
   public void message() {
       System.out.println("Warning: Dates in calendar are closer than they appear.");
   }

} </syntaxhighlight>

Class Template:Java represents the superclass and implements a method call Template:Java. The subclass called Template:Java inherits every method that could be in the Template:Java class. Class Template:Java overrides the method Template:Java, replacing its functionality from Template:Java.

<syntaxhighlight lang="java"> Thought parking = new Thought(); parking.message(); // Prints "I feel like I am diagonally parked in a parallel universe."

Thought dates = new Advice(); // Polymorphism dates.message(); // Prints "Warning: Dates in calendar are closer than they appear." </syntaxhighlight>

When a subclass contains a method that overrides a method of the superclass, then that (superclass's) overridden method can be explicitly invoked from within a subclass's method by using the keyword Template:Java.<ref name="lewis-loftus" /> (It cannot be explicitly invoked from any method belongings to a class that is unrelated to the superclass.) The Template:Java reference can be

<syntaxhighlight lang="Java"> public class Advice extends Thought {

     @Override
     public void message() {
         System.out.println("Warning: Dates in calendar are closer than they appear.");
         super.message();  // Invoke parent's version of method.
     }

</syntaxhighlight>

There are methods that a subclass cannot override. For example, in Java, a method that is declared final in the super class cannot be overridden. Methods that are declared private or static cannot be overridden either because they are implicitly final. It is also impossible for a class that is declared final to become a super class.<ref name="deitel">Deitel & Deitel 2001, p.474</ref>

KotlinEdit

In Kotlin we can simply override a function like this (note that the function must be Template:Java):

<syntaxhighlight lang="kotlin"> fun main() {

   val p = Parent(5)
   val c = Child(6)
   p.myFun()
   c.myFun()

}

open class Parent(val a : Int) {

   open fun myFun() = println(a)

}

class Child(val b : Int) : Parent(b) {

   override fun myFun() = println("overrided method")

} </syntaxhighlight>

PythonEdit

In Python, when a subclass contains a method that overrides a method of the superclass, you can also call the superclass method by calling Template:Python<ref name="python-3-super">Template:Python in Python 3 - see https://docs.python.org/3/library/functions.html#super Template:Webarchive</ref> instead of Template:Python. Example:

<syntaxhighlight lang="python"> class Thought:

   def __init__(self) -> None:
       print("I'm a new object of type Thought!")
   def message(self) -> None:
       print("I feel like I am diagonally parked in a parallel universe.")

class Advice(Thought):

   def __init__(self) -> None:
       super(Advice, self).__init__()
   def message(self) -> None:
       print("Warning: Dates in calendar are closer than they appear")
       super(Advice, self).message()

t = Thought()

  1. "I'm a new object of type Thought!"

t.message()

  1. "I feel like I am diagonally parked in a parallel universe.

a = Advice()

  1. "I'm a new object of type Thought!"

a.message()

  1. "Warning: Dates in calendar are closer than they appear"
  2. "I feel like I am diagonally parked in a parallel universe.
  1. ------------------
  2. Introspection:

isinstance(t, Thought)

  1. True

isinstance(a, Advice)

  1. True

isinstance(a, Thought)

  1. True

</syntaxhighlight>

RubyEdit

In Ruby when a subclass contains a method that overrides a method of the superclass, you can also call the superclass method by calling super in that overridden method. You can use alias if you would like to keep the overridden method available outside of the overriding method as shown with 'super_message' below.

Example:

<syntaxhighlight lang="ruby"> class Thought

 def message
   puts "I feel like I am diagonally parked in a parallel universe."
 end

end

class Advice < Thought

 alias :super_message :message
 def message
   puts "Warning: Dates in calendar are closer than they appear"
   super
 end

end </syntaxhighlight>

NotesEdit

Template:Reflist

See alsoEdit

ReferencesEdit

  • Deitel, H. M & Deitel, P. J.(2001). Java How to Program (4th ed.). Upper Saddle River, NJ: Prentice Hall.
  • Lewis, J. & Loftus, W. (2008). Java: Software Solutions (6th ed.). Boston, MA: Pearson Addison Wesley.
  • Malik, D. S.(2006). C++ Programming: Program Design Including Data Structure. (3rd ed.). Washington, DC: Course Technology.
  • Flanagan, David.(2002).Java in a Nutshell.Retrieved from http://oreilly.com/catalog/9780596002831/preview#preview
  • Meyer, Bertrand (2009). Touch of Class: Learning to Program Well with Objects and Contracts. Springer.

External linksEdit