继承与多态

继承是一种由已有的创建新类的机制。利用继承,可以先定义一个公共属相的一般类,根据该一般类在定义具有特殊属性的子类,子类继承一般类的属性和行为,并且根据需要增加它自己心的属性和行为。
有继承而得到的类称为子类,被继承的类称为父类,也叫超类,需要特别注意的一点是,Java和C++不一样,Java不支持多重继承,即子类只能有一个父类。
子类对象的特点。
当子类的构造方法创剪一个子类的对象时,不仅子类中声明的成员变量被分配了内存,而且父类的成员变量也分配了内存空间,但只将其中一部分作为分配给子类的变量。也就是说,父类中的private成员变量尽管分配了内存空间,也不作为子类对象的变量,即子类不继承父类的私有成员变量,同样,如果子类和父类不在同一个包中,尽管父类的友好成员变量分配了内存空间,但是也不作为子类对象的变量,即如果子类和父类不在同一个包中,子类不继承父类的友好成员变量。(备注:友好成员变量:不加修饰符private、protect 、public定义的变量)
访问限制修饰符按照访问权限从高到低排列的顺序的是:public、protect、友好的、private,private修饰符访问权限最底,只能在本类中访问。
通过以上的解释,我们有这样的感觉:子类创建对象时,似乎的浪费了一些内存,因为当用子类创建对象时,父类的成员变量也都分配了内存空间,但是只将其中一部分作为子类对象的变量,比如,父类中的private成员变量尽管分配了内存空间,也不作为子类对象的变量。当然他们也不是父类某个对象的变量,因为我们根本就没有使用父类创建的任何对象。这部分内存似乎就变成了垃圾,但是,实际的情况并非如此。我们需要注意的是,子类中还有部分方法是从父类继承的,这部分方法却可以操作这部分位继承的变量。
下面举个例子:
父类

package Example6;

public class People {
    private int averHeight = 166;
    public int getAverHeight(){
        return averHeight;
    }
}

子类:

package Example6;

public class ChinaPeople extends People {
    int height;
    public void setHeight(int h){
        //height = h + averHeight; //这种写法是非法的,子类并没有继承averHeight这个变量
        height = h;
    }
    public int getHeight(){
        return height;
    }
}

主函数

package Example6;

public class Demo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ChinaPeople chinaPeople = new ChinaPeople();
        System.out.println("子类对象未继承的averHeight的值是:" 
        + chinaPeople.getAverHeight());
        chinaPeople.setHeight(170);
        System.out.println("子类对象实例变量的height的值是:" 
                + chinaPeople.getHeight());
    }

}

调试结果:

子类对象未继承的averHeight的值是:166
子类对象实例变量的height的值是:170

一个小应用练习:
问题:
用类封装手机的基本属性和功能,要求手机既可以使用移动公司的SIM卡,也可以使用联通公司的SIM卡(可以使用任何公司提供的SIM卡)。
1、问题分析
如果涉及的手机类中具有某个具体的公司,比如移动公司,声明了对象,那么手机就缺少弹性,无法使用其他公司的SIM卡,因为一旦用户需要使用其他公司的SIM卡,就需要修改手机类中的代码,比如增加其他公司声明的成员变量。
如果每当用户有了新的需求,就会导致修改类的某部分代码,那么久应该将这部分代码从该类中分割出去,使它和类中其他稳定的代码之间是松耦合的关系(否则系统缺乏弹性,就很难再维护了),即将每种可能的变化对应地交给抽象类的子类去负责完成。
2、设计抽象类
根据以上对问题的分析,首先设计一个抽象类的SIM,该抽象类有三个抽象方法 giveNumber()、setNumber()、giveCorpName(),那么SIM的子类必须实现giveNumber、setNumber和giveCorpName()方法。
3、设计手机类
设计MobileTelephone类(模拟手机),改类有一个useSIM(SIM card)方法,改方法的参数是SIM类型。很显然,参数card可以是抽象类SIm的任何一个子类对象的上转型对象,即参数card可以调用SIM的子类重写的giveNumber()方法显示手机所使用的号码,调用子类重写的giveCorpName()党阀显示该号码所属的公司。
下面是详细的代码:
首先设计抽象类SIM.java

package Example13;

public abstract class SIM {
    public abstract void setNumber(String n);
    public abstract String giveNumber();
    public abstract String giveCorpNumber();
}

主方法:

package Example13;

public class MobileTelephone {
    SIM card;
    public void useSIM(SIM card){
        this.card = card;
    }
    public void showMess(){
        System.out.println("当前使用的卡是:" + card.giveCorpNumber() + "提供的");
        System.out.println("当前使用的手机号码是:" + card.giveNumber());
    }
}

抽象子类1:

package Example13;

public class SIMOfChinaMible extends SIM {
    String number;

    public void setNumber(String n) {
        this.number = n;
    }

    public String giveNumber() {
        return number;
    }

    public String giveCorpNumber() {
        return "中国移动";
    }

}

抽象子类2

package Example13;

public class SIMOfUnicom extends SIM {
    String number;
    public void setNumber(String n) {
        this.number = n;
    }

    public String giveNumber() {
        return number;
    }

    public String giveCorpNumber() {
        return "中国联通";
    }

}

主函数调用

package Example13;

import javax.xml.transform.Templates;

public class Application {

    public static void main(String[] args) {
        MobileTelephone mobileTelephone = new MobileTelephone();
        SIM sim = new SIMOfChinaMible();
        sim.setNumber("13884656565");
        mobileTelephone.useSIM(sim);
        mobileTelephone.showMess();
        sim = new SIMOfUnicom();
        sim.setNumber("15659938888");
        mobileTelephone.useSIM(sim);
        mobileTelephone.showMess();
    }

}

调试结果:

当前使用的卡是:中国移动提供的
当前使用的手机号码是:13884656565
当前使用的卡是:中国联通提供的
当前使用的手机号码是:15659938888

关于继承和多态的总结
1、继承的一种由已有的类创建新类的机制。利用继承,我们可以先创建一个公有的属性的一般类,根据该一般类再创建具有特殊属性的新类。
2、所谓子类继承父类的成员变量作为自己的一个成员变量,就好像是他们在子类中直接声明一样,可以被子类中自己声明的任何实例方法操作。
3、所谓子类继承父类的方法作为自己的一个方法,就好像是他们在子类中直接声明一样,可以被子类中自己声明的任何方法调用。
4、子类继承的方法只能操作子类继承和隐藏的成员变量。
5、子类重写或者新增方法能操作子类继承和新声明的成员变量,但是不能够直接操作隐藏的成员变量。(需要使用关键字super操作隐藏的成员变量)。
6、多态是面向对象编程的又一重要特性。子类可以就体现多态,即子类可以根据各自的需要重写父亲的某个方法,子类通过方法的重写可以把父亲的状态和行为改变为自身的状态和行为。
7、在使用多态设计程序设计时,要熟练使用上转型对象以及面抽象编程的思想,以便体现程序设计所提倡的“开 - 闭原则”。(就是让设计的系统应当对扩展开放,对修改关闭)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值