/*The Method selection algorithm *Consider the function call foo.bar(x1), where foo has static type TPrime, and has dynamic type T1 At compile time, the compiler verifies that TPrime has a method that can handle T1. It then records the signature of this method. *****Note: If there are multiple methods that can handle T1, the compiler records the "most specific" one. For example, if T1=Dog, and TPrime has bar(Dog) and bar(Animal), it will record bar(Dog); ***** At runtime, if foo's dynamic type overrides the recorded signature, use the overridden method. Otherwise, use TPrime's version of the method. * */ public interface Animal { default void greet(Animal a) { print("hello animal"); } default void sniff(Animal a) { print("sniff animal"); } default void flatter(Animal a) { print("u r cool animal"); } } public class Dog implements Animal { void sniff(Animal a) { print("dog sniff animal"); } void flatter(Dog a) { print("u r cool dog"); } } Animal a = new Dog(); Dog d = new Dog(); a.flatter(d); /*Compiler asks "Is there a method in Animal that can handle * Dog"? Yes! * flatter(Animal a) " * It then records the signature flatter(Animal a). * */ /*----------------------------- *Interface vs. Implementation Inheritance. * Interface Inheritance(what): * 1.1 Allows you to generalize code in a powerful, simple way. * *Implementation Inheritance(how): *Allowas code-reuse:Subclasses can rely on superclasses or interfaces. */
2. Interface and inherience.
/*Method. Overriding vs. Overloading. * If a "subclass" has a method with the exact same signature * as int the "superclass", we say the subclass overrides the *the method. 1.Animal's subclass Pig overrides the makeNoise() method. 2.Methods with the same name but different signatures are overload. * */ /*If a subclass has a method with the exact same signature * as in the superclass, we say the subclass overrides the method. *1. Even if you don't write @Override, subclass still overrides the method. @Override is just an optional reminder that you are overriding. * *Why use @Override ? 1. Main reason: Protects against typos. 1.1 If you say @Override, but it the method isn't actually overriding anything, you'll get a compiler error. 1.2 public void addLats(Item x). 2. Reminds programmer that method definition came from somewhere higher up in the inheritance hierarchy. */ /*Interface Inheriance. * Specify the capabilities of a subclass using the implements * keyword is known as interface inheritance. * 1.1 Interface: The list of all method signatures. * 1.2 Inheritance: The subclass "inherits" the interface * from a superclass. * 1.3 Specifies what the subclass can do, but not how. * 1.4 Subclasses must override all of the these methods.! * will fail to compiler otherwise. */ /* Two seemingly contradictory facts: * #1. When you set x = y or pass a parameter, * you're just copying the bits. * #2. A memory box can only hold 64 bit addresses for the appropriate * type. * String x can never hold the 64 bit address of a Dog. * * Copying the Bits. * Answer: If X is a superclass of Y, then memory boxes * for X may contain Y, * 1. An AList is-a List. * 2. Therefore List variable can hold ALList addresses. * / /*Implementation Inheritance * Interface inheritance: * 1.1 Subclass inherits signature, but NOT implementaion. * * For better or worse, Java also allows implementaion inheritance. * --Subclasses can inherit signatures AND implementation. * *Use the default keyword to specify a method that subclasses should inherit from an interface. 1.1 Example: Let's add a default print() method to List61B.java. * */ public interface Animal { public void makeNoise(); } public class Pig implements Animal { public void makeNoise() { //override. System.out.print("oink"); } } public class Dog implements Animal { public void makeNoise(Dog x) { //overload. // .... } }