永中首页 | 产品聚焦 | 销售渠道 | 服务支持 | 教育专栏 | 二次开发 | 在线订购 | 产品注册 | 免费下载 | 新闻中心 | 关于永中
发新话题
打印

专题研究:关于继承-——希望能起到抛砖引玉的作用

专题研究:关于继承-——希望能起到抛砖引玉的作用

/**
* @author mljinbo
* 在面向对象的继承方面,我们应尽量地继承于抽象类,而不是具体类,(如果是基于具体类的继承,很容易使对象在定义equals方法时出问题-----如传递性上;
* 抽象类的存在,就是用来继承的从来达到复用的目的,具体类的存在,是为了实现的)但有时是不得已要继承一个具体类,此时基类(父类)、派生类(子类)它们的方法和变量,
* 在调用时如何呢?
*/
  class Father{
        String name="father";
        public void who(){
                System.out.println("I am "+ name ) ;
                say();
        }
        public void bye(){
                System.out.println(name+ ": GoodBye" ) ;
        }
        public  void say(){
                System.out.println("Father :hello"  ) ;
        }

}
class Son extends Father{
        String name="son";
        public void who(){
               
                System.out.println("Son :I am "+ name ) ;
                say( ) ;
        }
       
       
        public  void say(){
                System.out.println("Son :hello" ) ;
        }
}
public class Demo  {
       public static void main(String[] args){
               /*当父类句柄变量变量f指向父类时,此时父类方法调用的全是自已的内容,如
                * f.who()调用的name 是Father.name;who调用的方法也是Father
                * 的方法是Father.say();此时该句柄变量所指的变量亦是Father.name即字符串"father"
                *
                */
               Father f=new Father();
                f.who();
                System.out.println(f.name);
                f.bye();
                System.out.println("\n\n" ) ;
               /*     输出结果为:
                *      I am father
                 *      Father :hello
                 *      father
                 *      father: GoodBye
                */
                
             /*当子类句柄变量变量向子类时,此时子类方法调用的全是自已的内容,如
                 * s.who()调用的name 是Son.name;s.who调用的方法也是Son
                 * 的方法Son.say();s.name所指的变量亦是Son自己的变量Son.name即字符串"son"
                 * 字类句柄变量所指的子类对象的没有对应的方法,则子类会调用从父类继承的方法。父类的方法会自动调用父类的变量Father.name
                 * 而不是子类的变量Son.name;
                 *
                 */
       Son s=new Son( ) ;
       s.who();
       System.out.println(s.name);
       s.bye();
       System.out.println("\n\n" ) ;
       /*输出结果为:
        * Son :I am son
        * Son :hello
        * son
        * father: GoodBye
*/
      
       /*当父类句柄变量指向子类时,
        * 此时句柄变量所指的方法调用的全是它实际所指对象的自已的内容,如
        * s.who()调用的name 是Son.name;s.who调用的方法也是Son
        * 的方法Son.say();但若用f.name ,则它指的是父类的内容Father.name
        */
      
       Father fs= s;
       //        f.who();
               fs.who();
               System.out.println(fs.name);
               fs.bye();
               /* 输出结果:
                *  Son :I am son
         *  Son :hello
         *  father
         *  father: GoodBye
         */
       }
      
}

关于为什么会这样,大家可从下面这段话里面找到启示
Since there are now two classes involved—the base class and the derived class—instead of just one, it can be a bit confusing to try to imagine the resulting object produced by a derived class. From the outside, it looks like the new class has the same interface as the base class and maybe some additional methods and fields. But inheritance doesn’t just copy the interface of the base class. When you create an object of the derived class, it contains within it a subobject of the base class. This subobject is the same as if you had created an object of the base class by itself. It’s just that from the outside, the subobject of the base class is wrapped within the derived-class object.---------------<<think in java>> 第三版Resuing classes

有不当的地方,还望更正......

[ Last edited by mljinbo on 2005-6-30 at 19:36 ]
人才和策略不一样,是最不容易被对手模仿的......

TOP

潜水的人不少啊,给个意见行不?

TOP

java中类似的状况不少,有时只能自己摸索,但就这一例来说,每个学java的人都应知道,大家专门给该例起了个形象的名称“戴帽子”,谁是帽子?当然是所谓的“field、或者变量”,戴在谁的头上,就是谁的

TOP

基类(父类)、派生类(子类)它们的方法和变量的调用在“虚拟机规范”中有明确规定:
The Java virtual machine specification
2.9 Fields
The variables of a class type are its fields. Class (static) variables exist once per class. Instance variables exist once per instance of the class. Fields may include initializers and may be modified using various modifier keywords.
If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in the superclasses and superinterfaces of the class. A class inherits from its direct superclass and direct superinterfaces all the fields of the superclass and superinterfaces that are accessible to code in the class and are not hidden by a declaration in the class. A hidden field can be accessed by using a qualified name (if it is static) or by using a field access expression that contains a cast to a superclass type or the keyword super.
2.10 Methods
A method declares executable code that can be invoked, passing a fixed number of values as arguments. Every method declaration belongs to some class. A class inherits from its direct superclass (§2.8.3) and any direct superinterfaces (§2.13.2) all the accessible methods of the superclass and superinterfaces, with one exception: if a name is declared as a method in the new class, then no method with the same signature (§2.10.2) is inherited. Instead, the newly declared method is said to override any such method declaration. An overriding method must not conflict with the definition that it overrides, for instance, by having a different return type. Overridden methods of the superclass can be accessed using a method invocation expression involving the super keyword.

[ Last edited by tedted on 2005-7-5 at 06:00 ]

TOP

发新话题