深入Java 面向对象编程 (二)继承与多态

回顾

如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象

static成员的最常见的例子是main(),因为在程序开始执行时必须调用main(),所以它被声明为static

声明为static的方法有以下几条限制:

它们仅能调用其他的static方法。

它们只能访问static数据。

1、继承


java继承与多态编程题库_父类


l 继承是面向对象非常重要的特点之一,用好继承能够使程序具有更好的可扩充性,减少程序的代码量

l 先来看看什么是继承

2.什么是继承

l 继承是一种由已有的类创建新类的机制。利用继承,我们可以先创建一个共有属性的一般类,根据该一般类再创建具有特殊属性的新类,新类继承一般类的状态和行为,并根据需要增加它自己的新的状态和行为

 

 

3.为什么要继承

l 代码冗余

l 程序难以更新

l 难以扩展

//卡车
public class Truck {
    String engine; //引擎
    String Wheel; //车轮
    String carport; //货舱
    public void run() {
        //定义车跑动的行为
    }
}


//轿车
public class Saloon_car {
    String engine; //引擎
    String Wheel; //车轮
    String airbag; //安全气囊
    public void run() {
        //定义车跑动的行为
    }
}

4.使用继承

l 继承使用的关键字是extends

//基类 :汽车
public class Car {
String engine;//引擎
String Wheel;//车轮
//……其他属性
public void run() {
// 定义车跑动的行为
        System.out.println("汽车在奔跑!");
}
}

//轿车
public class Saloon_car extends Car{
安全气囊
}
 

//卡车
public class Truck extends Car { 
    String carport; //货舱
}

 

5、方法覆盖1

l 不管是普通汽车,还是卡车和轿车,他们的运转都是一样的,结果均输出“汽车在奔跑”,这是不恰当的

l 卡车和轿车的运转应该是有自己的独立方式的,不应当和普通汽车保持一致

l 也就是说,子类需要对父类的run方法加以改进,变成子类自己的run方法,这就需要在子类中重新编写run方法,覆盖父类的run方法,这种做法在Java中叫做方法的覆盖(Override,又称方法重写)

 

6、方法覆盖2


//汽车
public class Car {
String engine;//引擎
String Wheel;//车轮
//……其他属性
public void run() {
定义车跑动的行为
     汽车在奔跑!");
}
}


//轿车
public class Saloon_car extends Car{
String airbag; //安全气囊
public void run() {
定义轿车
轿车在高速路上奔驰!");
}
}
 
 
//卡车
public class Truck extends Car { 
String carport; //货舱
public void run() {
// 定义卡车
       卡车在工地上忙碌!");
}
}

 

7、方法覆盖与方法重载

l 要注意重载和重写的区别,重载既可以发生于一个类,也可以发生于子类与父类之间(子类继承父类方法,同时完成方法重载),而重写,则只能是子类重写父类方法

 

8、多态

l 多态指的就是多种形态,例如,同样是水的成份,但有液态水及冰的多种形态,同样是二氧化碳,就存在气态及液态等多种形态,同样是猫科动物,就有猫和老虎之别

l 继承的表现就是多态


/*对汽车及其子类进行测试,接收汽车对象*/
public void test(Car car){
car.run();
}
…………
public static void main(String[] args) {
CarTest1 ct = new CarTest1();
Car car ;
car = new Car(); //产生普通汽车
ct.test(car);
car = new Saloon_car(); //产生轿车
ct.test(car);
car = new Truck(); //产生卡车
ct.test(car);
}


注意

l 可以看到,同样是Car类的对象,既可以是汽车,也可以是卡车,还可以是轿车,父类句柄可以接收子类对象。在调用test方法时,传递的都是Car类的对象,但是输出什么样的结果取决于该父类句柄所绑定(指向)的到底是什么对象。这在Java中通常叫做run-time binding(运行时绑定)

l 由父类引用创建的对象,只能调用子类从父类继承的方法(当然包含重写的方法),不能调用自己扩展的方法。就像我们说:豹子是动物(向上转型),也可说:豹子会奔跑(调用从父类继承的方法),而不能说:动物是豹子(向下转型),也不能说:动物会爬树(向上转型的对象不能调用子类对象扩展的方法)。

 

9、Super关键字

 

 

l 在讲解构造方法的章节,我们提到了this关键字,this关键字用于表示类的对象自身,在使用中的所有未指明调用者的属性和方法,其前面均由JVM自动加上this,表示调用者自身

l 在某些时候,子类需要调用父类的某些方法

l 除了调用父类同名方法外,super还广泛的运用于构造方法内

 

public class Employee {
    String name;
    public Employee(String name) {
        this.name = name;
    }
}
public class Manager extends Employee {
String department;
public Manager(String name, String department) {
super(name);
this.department = department;
}
}

10、Object类

l Java世界中,任意一个类均直接或间接由一个类演绎而来,这个类就是Object类,Object 是类层次结构的根类,每个类都使用 Object 作为超类。所以,每个类都具有Object类所定义的特征

 

方法

描述

toString():

返回一个“以文本方式表示”此对象的字符串

hashCode()

返回该对象的哈希码值

equals()

指示某个其他对象是否与此对象“相等”

 

11、final关键字

l 通常情况下,为了扩充类的功能,我们允许类的继承

l 但在某些情况下,例如,Sun公司提供的某些功能类,如进行数学运算的类、对字符串处理的类等,由于已经比较完美,不需要再修订;当然,也可能出于安全方面的理由,我们不希望进行子类化,或者考虑到执行效率问题,希望确保涉及这个类各对象的所有行动都要尽可能地有效。这个时候就有必要禁止客户继承。那么如何实现禁止继承的功能呢?这就要靠final关键字来完成了

12、final修饰类

/**
 * 四则运算类,是最终类
 * @author svse
 *
 */
public final class MathProcess {…………}

 
 
 
 
final修饰方法
/**
 * 四则运算类,是最终类
 * @author svse
 */
public class MathProcess {
public final int add(int i,int j){
return i+j;
}…………

final修饰属性和变量

l final修饰类,则类不能被继承,修饰方法,则方法不能被重写,如果修饰属性的话,那么这个属性的值是不能被修改的

public class Dog {
//属性
final String shout = "汪汪";
public static void main(String[] args) {
Dog dog = new Dog();
dog. shout="喵喵";
//普通变量
final int age ;
age = 0;
age = 1;
}
}

final修饰对象引用

public class CatDemo {
final Cat cat = new Cat();
public static void main(String[] args) {
//更改cat的属性值
CatDemo cd = new CatDemo();
cd.cat.name = "小花";
cd.cat.name = "小花花";
//更改cat
cd.cat = new Cat();
}
}

final修饰对象引用

l 可以看到,对cat用final修饰后,可以修改cat的属性值,但是不能再修改cat对象的引用。这和之前的讲述并无冲突,修改了cat的属性值,但cat本身地址并未变化

总结

l Object是Java中所有其他类的父类

l 使用extends关键字可继承父类产生一个新的子类

l 子类可以拥有与父类同名,但功能不同的方法,即覆盖父类方法

l 子类可通过super关键字获得父类的方法

l Final关键字可以限定对象、变量、方法、类,使他们不能被修改