C++和Java中关于继承的点点滴滴

来源:互联网 发布:约翰霍普金斯大学 知乎 编辑:程序博客网 时间:2024/06/03 12:34

 

1. Java篇

import java.util.ArrayList;

import java.util.Stack;

 

    class Super

    {

        static String greeting() { return "Goodnight"; }

        String name() { return "Richard"; }

    }

    class Sub extends Super

    {

        static String greeting() { return "Hello"; }

        String name() { return "Dick"; }

        String name2() { return "Dick2"; }

    }

    public class Test3

    {

        public static void main(String[] args)

        {

            Super s = new Sub();

            //s.name2();

            System.out.println(s.greeting() + ", " + s.name());

        }

    }

 

 

Test3会输出什么呢? s在Java VM空间是Super还是Sub? s.name2会不会有编译错误?

 

执行D:/workspace/2009Java/test/bin>D:/Java/jdk/bin/javap -c Test3 >Test3.bytecode, 来看看java的opcode.

 

Compiled from "Test3.java"

public class Test3 extends java.lang.Object{

public Test3();

  Code:

   0:aload_0

   1:invokespecial#8; //Method java/lang/Object."<init>":()V

   4:return

 

public static void main(java.lang.String[]);

  Code:

   0:new#16; //class Sub

   3:dup

   4:invokespecial#18; //Method Sub."<init>":()V

   7:astore_1

   8:getstatic#19; //Field java/lang/System.out:Ljava/io/PrintStream;

   11:new#25; //class StringBuilder

   14:dup

   15:invokestatic#27; //Method Super.greeting:()Ljava/lang/String;

   18:invokestatic#33; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;

   21:invokespecial#39; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V

   24:ldc#42; //String , 

   26:invokevirtual#44; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

   29:aload_1

   30:invokevirtual#48; //Method Super.name:()Ljava/lang/String;

   33:invokevirtual#44; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

   36:invokevirtual#51; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

   39:invokevirtual#54; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

   42:return

 

}

 

invokevirtualInvoke instance method, dispatch based on run-time type 
invokestatic

Invoke a class (static) method

 

 

2. Run-time type is Sub, Class type is Super. 所以会有以上的输出. 至于s.name2的错误,编译器检查的结果.

 

2. C++篇

 

 

import java.util.ArrayList;

import java.util.Stack;

 

    class Super

    {

        static String greeting() { return "Goodnight"; }

        String name() { return "Richard"; }

    }

    class Sub extends Super

    {

        static String greeting() { return "Hello"; }

        String name() { return "Dick"; }

        String name2() { return "Dick2"; }

    }

    public class Test3

    {

        public static void main(String[] args)

        {

            Super s = new Sub();

            //s.name2();

            System.out.println(s.greeting() + ", " + s.name());

        }

    }

 

 

这样的输出又是什么呢?

 

 

Coming from a C# background you never need to worry about issueslike as you always pass objects by reference and there is no such thingas copy constructors, assignment operator overloads and the obvious oneis that all objects are on the heap meaning that assigning a to b meansb and a point to the same thing.

In c++ you have the choice to create an object on the free store orcreate it on the stack. When objects are store on the stack and a isassigned to b then the copy constructor or the asignment overload willrun and copy the object to the other object doing a memberwise /shallow copy.

This becomes a problem when you have a function that takes a baseclass object without reference semantics. You think that it supportspolymorphism but it does not. when you invoke the virtual method italways calls the super classes methods. Why? This is because it wascopied to a super class object and all reference to the sub class waslost.

 

原创粉丝点击