面向对象编程(九)——面向对象三大特性之继承以及重写、Object类的介绍

面向对象三大特性

面向对象三大特征:继承封装/隐藏多态(为了适应需求的多种变化,使代码变得更加通用!)

封装:主要实现了隐藏细节,对用户提供访问接口,无需关心方法的具体实现。
继承:很好的实现了代码的复用,提高了编程效率。 
多态:程序的可扩展性及可维护性增强。

继承(extends)

 

  • 类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。(从OOA、OOD即面向对象设计的角度考虑)
  • 继承可以提高代码的复用性!(从OOP的角度考虑)
  • extends的意思是“扩展”。子类是父类的扩展。

【例1】不采用继承,这里屡次使用Animal里面的东西,很麻烦。所以很自然产生继承的概念。

//一个源文件可以定义多个类
//动物Animal类
public class Animal {
    String eye;
    
    public void run(){
        System.out.println("跑跑");
    }
    
    public void eat(){
        System.out.println("吃吃");
    }
}
//哺乳动物Mammal类
 class Mammal{
     String eye;
    public void run(){
        System.out.println("跑跑");
    }
    
    public void eat(){
        System.out.println("吃吃");
    }
    
    public void taiSheng(){
        System.out.println("我是胎生");
    }
}
 //爬行动物
 class Paxing{
     String eye;

     public void run(){
         System.out.println("跑跑");
     }

     public void eat(){
         System.out.println("吃吃");
     }
     public void eggSheng(){
         System.out.println("我是卵生");
     }
 }

采用继承后:

//一个源文件可以定义多个类
//动物Animal类
public class Animal {
    String eye;
    
    public void run(){
        System.out.println("跑跑");
    }
    
    public void eat(){
        System.out.println("吃吃");
    }
}
//哺乳动物Mammal类
 class Mammal extends Animal{
     //Mammal类扩展自Animal类,继承它的一切,Animal类里面有什么,Mammal类就有什么,再加上自己的
    public void taiSheng(){
        System.out.println("我是胎生");
    }
}
 //爬行动物
 class Paxing extends Animal{
     
     public void eggSheng(){
         System.out.println("我是卵生");
     }
 }

【继承的小结】

  • 继承是is-a关系(包含关系);
  • 子类继承父类,可以得到父类的全部非private属性和方法(除了父类的构造方法,但可以通过super关键字来调用父类的构造方法)
  • Java中只有单继承,(一个类只有一个直接父类),但可以多层继承。没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难以维护。就像我们现实中,如果你有多个父母亲,那么是一个多么混乱的世界啊。多继承,就是为了实现代码的复用性,却引入了复杂性,使得系统类之间的关系混乱。
  • 继承关系可以传递。
  • Java中的多继承,可以通过接口来实现
  • 如果定义一个类时,没有调用extends,则它的父类是java.lang.Object.
  • 不同的叫法:超类、父类、基类、子类、派生类

 

 

 

 

 

 

 

 

 

 

方法的重写(覆盖,override)

如何定义重写:在Java程序中,类的继承关系可以产生一个子类,子类继承父类,它具备了父类所有的特征,继承了父类所有的方法和变量。子类可以定义新的特征,当子类需要修改父类的一些方法进行扩展,增大功能,程序设计者常常把这样的一种操作方法称为重写,也叫称为覆写或覆盖。

重写体现了Java优越性,重写是建立在继承关系上,它使语言结构更加丰富。在Java中的继承中,子类既可以隐藏和访问父类的方法,也可以覆盖继承父类的方法。在Java中覆盖继承父类的方法就是通过方法的重写来实现的。

所谓方法的重写是指子类中的方法与父类中继承的方法有完全相同的返回值类型、方法名、参数个数以及参数类型。这样,就可以实现对父类方法的覆盖。

  • 在子类中可以根据需要对从基类中继承来的方法进行重写。
  • 重写方法必须和被重写方法具有相同的方法名称参数列表返回类型
  • 重写方法不能使用比被重写方法更严格的访问权限(由于多态)
  • 注:重载(overload)和重写没有任何关系。

 【例子code】

父类Person类:

public class Person {
         private int age;
        private String name;
        
        public void setAge(int age){
            this.age = age;
        }
        public void setName(String name){
            this.name = name;
        }
        public int getAge(){
            return age;
        }
        public String getName(){
            return name;
        }
        
        public String getInfo(){
            return "Name is:"+name+",Age is "+age;
        }
}

子类Student类:

public class Student extends Person{

    private String school;

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }
    
    public String getInfo(){
        return "Name is:"+getName()+",Age is "+getAge()+",School is:"+school;
    }
}

测试代码:

public class TestOverRide {

    public static void main(String[] args) {
        Student student = new Student();
        Person person = new Person();
        person.setAge(1000);
        person.setName("lili");

        student.setAge(23);
        student.setName("vic");
        student.setSchool("shnu");

        System.out.println(person.getInfo());
        System.out.println(student.getInfo());
    }

}

运行结果:

Name is:lili,Age is 1000
Name is:vic,Age is 23,School is:shnu
View Code

Object类

  Object类在JAVA里面是一个比较特殊的类,JAVA只支持单继承,子类只能从一个父类来继承,如果父类又是从另外一个父类继承过来,那他也只能有一个父类,父类再有父类,那也只能有一个,JAVA为了组织这个类组织得比较方便,它提供了一个最根上的类,相当于所有的类都是从这个类继承,这个类就叫Object。所以Object类是所有JAVA类的根基类,是所有JAVA类的老祖宗。所有的类,不管是谁,都是从它继承下来的。

    1. Object类是所有Java类的根基类
    2. 如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类

查看Object源码,可以留意到一些方法:

equals()方法

toString()方法

toString方法介绍

  

  一个字符串和另外一种类型连接的时候,另外一种类型会自动转换成String类型,然后再和字符串连接。基础的数据类型int,float,double转换成字符串比较简单,按照它们的数字转换过来就成了,可以引用类型呢,Person p = new Person();一个字符串加上这个p,你就不知道要怎么把这个p转换成字符串了,因为这个p是一个引用类型。

  •  重写:toString方法
    • 默认返回:包名+类名+@+哈希码
    • 哈希码是根据对象内存位置生成,唯一不重复
    • toString方法可以被重写

【例子】Mobile类

public class Mobile {//如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类
    //重写父类Object类的toString()
  /**
      * 在这里重写了Object类里面的toString()方法后,
      * 引用对象自动调用时调用的就是重写后的toString()方法了,
      * 此时打印出来的显示信息就是我们重写toString()方法时要返回的字符串信息了,
     * 不再是那些看不懂的哈希编码了。
      */
    public String toString() {
        return "我是一部移动电话";
        }
}

测试Object类:

public class TestObject {

    public static void main(String[] args) {
        
        Object obj=new Object();
        Object obj1=new Object();
        System.out.println(obj.toString());//java.lang.Object@c3c749:类名+@+哈希码
        System.out.println(obj1.toString());//哈希码是根据地址来的。
        
        System.out.println(obj == obj1);//false
        System.out.println(obj.equals(obj1));//false
        
        Mobile m=new Mobile();
        System.out.println(m.toString());
      /**
          * 如果没有重写toString方法,那么输出来的默认的字符串内容是“类名+哈希编码”,
          * 如:dog=cn.galc.test.Dog@150bd4d
          * 这里的d就是一个引用类型,打印的时候,这个引用类型d会自动调用toString()方法将自己转换成字符串然后再与字符串”d:=”相连,
         * 然后一起被打印出来。d为什么可以自动调用toString()方法呢,Dog类里面也没有声明这个toString()方法。
          * 这是因为toString()方法是Object类里面的方法,而所有的类都是从Object类继承下来的,
         * Dog类当然也不例外,所以Dog类继承了Object类里面的toString()方法,
          * 所以Dog类的对象当然可以直接调用toString()方法了。
          * 但是Dog类对继承下来的toString()方法很不满意,
          * 因为使用这个继续下来toString()方法将引用对象转换成字符串输出时输出的是一连串令人看不懂的哈希编码。
          * 为了使打印出来的信息使得正常人都能看得懂,因此要在Dog类里面把这个继承下来的toString()方法重写,
         * 使得调用这个toString()方法将引用对象转换成字符串时打印出来的是一些正常的,能看得懂的信息。
          * 在子类重写从父类继承下来的方法时,从父类把要重写的方法的声明直接copy到子类里面来,
          * 这样在子类里面重写的时候就不会出错了。
          */
    }

}

 

执行结果:

java.lang.Object@c3c749
java.lang.Object@150bd4d
false
false
我是一部移动电话
View Code

 任何一个类都是从Object类继承下来的,因此在任何一个类里面都可以重写这个toString()方法。toString()方法的作用是当一个引用对象和字符串作连接的时候,或者是直接打印这个引用对象的时侯,这个引用对象都会自动调用toString()方法,通过这个方法返回一个表示引用对象自己正常信息的字符串,而这个字符串的内容由我们自己去定义,默认的字符串内容是“类名+哈希编码”。因此我们可以通过在类里面重写toString()方法,把默认的字符串内容改成我们自己想要表达的正常信息的字符串内容。


 ps:

myeclipse/eclipse查看继承结构(类型层次结构):鼠标指针放在类名上,按住ctrl+t;或对类名点击鼠标右键,选择open Type Hierarchy(或者F4)

Mammal类继承了Animal,Animal继承了Object

posted @ 2016-02-01 15:42  萌小Q  阅读(1478)  评论(0编辑  收藏  举报