Overloading overriding runtime type and object orientation (1)

loading|object

6)Overloading overriding runtime type and object orientation
Objective 1)
State the benefits of encapsulation in object oriented design and write code that implements tightly encapsulated classes and the relationships "is a" and "has a".

Encapsulation involves hiding data of a class and allowing access only through a public interface.

The separation of interface and implementation makes it easier to modify the code within a class without breaking any other code that uses it.

encapsulation, inheritance, polymorphism are three principal characteristics of Object Oriented programming.

Implementing OO relationships
·    “is a” relationship is implemented by inheritance (extends keyword)
·    “has a” relationship is implemented by providing the class with member variables.

Overloading and Overriding
·    Overloading is an example of polymorphism. (operational / parametric)
·    Overriding is an example of runtime polymorphism (inclusive)
·    A method can have the same name as another method in the same class, provided it forms either a valid overload or override

Objective 2)
Write code to invoke overridden or overloaded methods and parental or overloaded constructors; and describe the effect of invoking these methods.

Overloading    Overriding
Signature has to be different. Just a difference in return type is not enough.    Signature has to be the same. (including the return type)
Accessibility may vary freely.    Overriding methods cannot be more private than the overridden methods.
Exception list may vary freely.    Overriding methods may not throw more checked exceptions than the overridden methods.  But can throw no exception.
Just the name is reused. Methods are independent methods. Resolved at compile-time based on method signature.    Related directly to sub-classing. Overrides the parent class method. Resolved at run-time based on type of the object.
Can call each other by providing appropriate argument list.    Overriding method can call overridden method by super.methodName(), this can be used only to access the immediate super-class’s method. super.super won’t work. Also, a class outside the inheritance hierarchy can’t use this technique.
Methods can be static or non-static. Since the methods are independent, it doesn’t matter. But if two methods have the same signature, declaring one as static and another as non-static does not provide a valid overload. It’s a compile time error.    static methods don’t participate in overriding, since they are resolved at compile time based on the type of reference variable. A static method in a sub-class can’t use ‘super’ (for the same reason that it can’t use ‘this’ for)Remember that a static method can’t be overridden to be non-static and a non-static method can’t be overridden to be static. In other words, a static method and a non-static method cannot have the same name and signature (if signatures are different, it would have formed a valid overload)
There’s no limit on number of overloaded methods a class can have.    Each parent class method may be overridden at most once in any sub-class. (That is, you cannot have two identical methods in the same class)

·    Variables can also be overridden, it’s known as shadowing or hiding. But, member variable references are resolved at compile-time. So at the runtime, if the class of the object referred by a parent class reference variable, is in fact a sub-class having a shadowing member variable, only the parent class variable is accessed, since it’s already resolved at compile time based on the reference variable type. Only methods are resolved at run-time.

public class Shadow {
  public static void main(String s[]) {
    S1 s1 = new S1();
    S2 s2 = new S2();
    
    System.out.println(s1.s); // prints S1
    System.out.println(s1.getS()); // prints S1
    System.out.println(s2.s); // prints S2
    System.out.println(s2.getS()); // prints S2

    s1 = s2;
    System.out.println(s1.s); // prints S1, not S2 -
                      // since variable is resolved at compile time
    System.out.println(s1.getS()); // prints S2 -
                     // since method is resolved at run time    
  }
}

class S1 {
  public String s = "S1";
  public String getS() {
    return s;
  }
}

class S2 extends S1{
  public String s = "S2";
  public String getS() {
    return s;
  }
}
In the above code, if we didn’t have the overriding getS() method in the sub-class and if we call the method from sub-class reference variable, the method will return only the super-class member variable value. For explanation, see the following point.

·    Also, methods access variables only in context of the class of the object they belong to. If a sub-class method calls explicitly a super class method, the super class method always will access the super-class variable. Super class methods will not access the shadowing variables declared in subclasses because they don’t know about them. (When an object is created, instances of all its super-classes are also created.) But the method accessed will be again subject to dynamic lookup. It is always decided at runtime which implementation is called. (Only static methods are resolved at compile-time)

public class Shadow2 {
  String s = "main";
  public static void main(String s[]) {
    S2 s2 = new S2();
    s2.display();  // Produces an output – S1, S2

    S1 s1 = new S1();
    System.out.println(s1.getS()); // prints S1
    System.out.println(s2.getS()); // prints S1 – since super-class method always
     // accesses super-class variable

  }
}

class S1 {
  String s = "S1";
  public String getS() {
    return s;
  }
  void display() {
    System.out.println(s);
  }
}

class S2 extends S1{
  String s = "S2";
  void display() {
    super.display();   // Prints S1
    System.out.println(s); // prints S2
  }
}

·    With OO languages, the class of the object may not be known at compile-time (by virtue of inheritance). JVM from the start is designed to support OO. So, the JVM insures that the method called will be from the real class of the object (not with the variable type declared). This is accomplished by virtual method invocation (late binding). Compiler will form the argument list and produce one method invocation instruction – its job is over. The job of identifying and calling the proper target code is performed by JVM.
·    JVM knows about the variable’s real type at any time since when it allocates memory for an object, it also marks the type with it. Objects always know ‘who they are’. This is the basis of instanceof operator.
·    Sub-classes can use super keyword to access the shadowed variables in super-classes. This technique allows for accessing only the immediate super-class. super.super is not valid. But casting the ‘this’ reference to classes up above the hierarchy will do the trick. By this way, variables in super-classes above any level can be accessed from a sub-class, since variables are resolved at compile time, when we cast the ‘this’ reference to a super-super-class, the compiler binds the super-super-class variable. But this technique is not possible with methods since methods are resolved always at runtime, and the method gets called depends on the type of object, not the type of reference variable. So it is not at all possible to access a method in a super-super-class from a subclass.

public class ShadowTest {
    public static void main(String s[]){
        new STChild().demo();
    }
}
class STGrandParent {
    double wealth = 50000.00;
    public double getWealth() {
        System.out.println("GrandParent-" + wealth);
        return wealth;
    }
}
class STParent extends STGrandParent {
    double wealth = 100000.00;
    public double getWealth() {
        System.out.println("Parent-" + wealth);
        return wealth;
    }
}
class STChild extends STParent {
    double wealth = 200000.00;

    public double getWealth() {
        System.out.println("Child-" + wealth);
        return wealth;
    }

    public void demo() {
        getWealth(); // Calls Child method
        super.getWealth(); // Calls Parent method
        //super.super.getWealth(); // Compiler error, GrandParent method cannot be accessed
        ((STParent)this).getWealth(); // Calls Child method, due to dynamic method lookup
    ((STGrandParent)this).getWealth(); // Calls Child method, due to dynamic method
      // lookup

        System.out.println(wealth); // Prints Child wealth
        System.out.println(super.wealth); // Prints Parent wealth
        System.out.println(((STParent)(this)).wealth); // Prints Parent wealth
        System.out.println(((STGrandParent)(this)).wealth); // Prints GrandParent wealth
    }
}

·    An inherited method, which was not abstract on the super-class, can be declared abstract in a sub-class (thereby making the sub-class abstract). There is no restriction. In the same token, a subclass can be declared abstract regardless of whether the super-class was abstract or not.
·    Private members are not inherited, but they do exist in the sub-classes. Since the private methods are not inherited, they cannot be overridden. A method in a subclass with the same signature as a private method in the super-class is essentially a new method, independent from super-class, since the private method in the super-class is not visible in the sub-class.

public class PrivateTest {
    public static void main(String s[]){
        new PTSuper().hi();     // Prints always Super
        new PTSub().hi();     // Prints Super when subclass doesn't have hi method
                 // Prints Sub when subclass has hi method
        PTSuper sup;
        sup = new PTSub();
        sup.hi();     // Prints Super when subclass doesn't have hi method
            // Prints Sub when subclass has hi method
    }
}

class PTSuper {
    public void hi() { // Super-class implementation always calls superclass hello
        hello();
    }
    private void hello() {     // This method is not inherited by subclasses, but exists in them.
            // Commenting out both the methods in the subclass show this.
            // The test will then print "hello-Super" for all three calls
            // i.e. Always the super-class implementations are called
        System.out.println("hello-Super");
    }
}

class PTSub extends PTSuper {
    public void hi() { // This method overrides super-class hi, calls subclass hello
        try {
            hello();
        }
        catch(Exception e) {}

    }

    void hello() throws Exception {     // This method is independent from super-class hello
                // Evident from, it's allowed to throw Exception
        System.out.println("hello-Sub");
    }
}

·    Private methods are not overridden, so calls to private methods are resolved at compile time and not subject to dynamic method lookup. See the following example.

public class Poly {
    public static void main(String args[]) {
        PolyA ref1 = new PolyC();
        PolyB ref2 = (PolyB)ref1;

        System.out.println(ref2.g());     // This prints 1
                    // If f() is not private in PolyB, then prints 2
    }
}

class PolyA {
    private int f() { return 0; }
    public int g() { return 3; }
}

class PolyB extends PolyA {
    private int f() { return 1; }
    public int g() { return f(); }
}

class PolyC extends PolyB {
    public int f() { return 2; }
}

时间: 2024-10-27 11:06:39

Overloading overriding runtime type and object orientation (1)的相关文章

Overloading overriding runtime type and object orientation (2)

loading|object Objective 3) Write code to construct instances of any concrete class including normal top level classes inner classes static inner classes and anonymous inner classes.Inner Classes·    A class can be declared in any scope. Classes defi

Overloading overriding runtime type and object ori

Objective 3) Write code to construct instances of any concrete class including normal top level classes inner classes static inner classes and anonymous inner classes.Inner Classes·    A class can be declared in any scope. Classes defined inside of o

C++:RTTI(RunTime Type Information)运行时类型信息 详解

RTTI, RunTime Type Information, 运行时类型信息, 是多态的主要组成部分, 通过运行时(runtime)确定使用的类型, 执行不同的函数,复用(reuse)接口. dynamic_cast<>可以 使基类指针转换为派生类的指针, 通过判断指针的类型, 可以决定使用的函数. typeid(), 可以判断类型信息, 判断指针指向位置, 在多态中, 可以判断基类还是派生类. 代码: /* * test.cpp * * Created on: 2014.04.22 * A

java中重载(overloading)与重写(overriding)

常见面试题是关于重载(overloading)方法和重写(overriding)方法的.  代码如下 复制代码  public class MethodOverrideVsOverload {     public boolean equals( MethodOverrideVsOverload other ) {       System.out.println("MethodOverrideVsOverload equals method reached" );       ret

Intellij idea使用postgresql 反向生成实例, &amp;#39;Basic&amp;#39; attribute type should not be &amp;#39;Object&amp;#39;

mapped type不能Object? 本人使用 intellij idea 15 , postgresql 9.4,在开发java ee . 在用 Hibernate时, 需要用数据库表反向生成实例,数据库中部分字段,是Int4,在反转的时候会爆出错误,下面是我的测试图,有木有大牛了解,可不可给给点解决方法,[生成后手动一个个修改回来除外],各种google过--唉,求教....   下拉框中并没有String或Integer 的选项,只有Object和序列化两种.选择序列化或者手动一个个敲

Understanding the Objective-C Runtime

Wednesday, January 20, 2010 Understanding the Objective-C Runtime The Objective-C Runtime is one of the overlooked features of Objective-C initially when people are generally introduced to Cocoa/Objective-C. The reason for this is that while Objectiv

Inside C++ object Model--对象模型概述

在C中, "数据"和"处理数据的操作"是分开声明的, 语言本身并没有支持"数据和函数"之间的关联性. 这种称为"procedural", 由一组算法函数所驱动, 他们处理的是共同的外部数据. 而C++, 则在程序风格, 更在程序的思考上有明显的差异, 它以ADT或class hierarchy的数据封装建立数据和操作的关联性. 在软件工程的眼光来看更为合理. 但是程序员往往出于效率和简易性考虑而选择C.   那么使用C++是否

《HTML5 开发实例大全》——1.25 使用&lt; object &gt;元素在网页中显示一个Flash

1.25 使用< object >元素在网页中显示一个Flash https://yqfile.alicdn.com/6f177bb72335e09f2608ee497c26d2a632c309e2.png" > 实例说明 本实例的功能是,使用< object >元素在网页中显示一个Flash,本实例的素材Flash文件是123.swf.在HTML 5 中,< object >元素的功能是定义一个嵌入的对象.请使用此元素向您的 XHTML 页面添加多媒体

详解Javascript中的Object对象_javascript技巧

Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是Object对象其实包含了很多很有用的属性和方法,尤其是ES5增加的方法,因此,本文将从最基本的介绍开始,详细说明了Object的常用方法和应用. 基础介绍 创建对象 首先我们都知道,对象就是一组相似数据和功能的集合,我们就是用它来模拟我们现实世界中的对象的.那在Javascript中,创建对象的方