03 子类与继承

基本内容:

  • java.lang包中的Object类是所有类的祖先类。
  • 子类与父类在同一包中,除了private都继承,private变量是子类的成员变量,但不分配内存;不在同一包中,除了private和友好的都继承。
  • protected变量和方法的继承要在同一个包内。
  • instanceof运算符:zhang instanceof People 返回结果为true。
  • 成员变量的隐藏:子类声明的成员变量和父类继承来的成员变量同名但类型不同。
  • 方法重写:同名同类型同参数,但重写方法的类型可以是子类型,如:返回People的子类型Student。方法重写可隐藏继承的方法,要调用被隐藏的方法或变量需用super关键字。
  • final类不能被继承,final方法不能被重写,final变量就是常量。

super关键字

  • 子类一旦隐藏了继承的成员变量,那么子类创建的对象就不再拥有该变量,而是归super关键字所有,被隐藏的方法也是。
  • 访问方式:super.x super.f()
  • 子类不继承父类的构造方法,但是用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法
    • super必须是子类构造方法中的第一条语句
    • 在子类的构造方法中,没有明显地写出super关键字来调用父类的某个构造方法的,默认有:super();
    • 应保证父类定义多个构造方法时有无参的,以防子类省略super时出现错误。

Super.java

package com.Clazz;

class Studentt{
    int number;
    String name;
    Studentt(){
    }
    Studentt(int number,String name){
        this.number = number;
        this.name = name;
        System.out.println("我的学号是:"+number+"  我的姓名是:"+name);
    }
}

class UniverStudent extends Studentt{
    boolean isMarried;
    UniverStudent(int number,String name,boolean b){
        super(number,name); //核心语句
        isMarried = b;
        System.out.println("婚否="+isMarried);
    }
}


public class Super {
    public static void main(String[] args) {
        UniverStudent zhang = new UniverStudent(9901,"Tom",false);
    }
}

运行结果:

我的学号是:9901  我的姓名是:Tom
婚否=false

对象的上转型对象

  • 说老虎是动物时,会失掉老虎独有的属性和功能,此为上溯思维方式

  • Animal animal;
    Tiger tiger = new Tiger();
    animal = tiger;
    //此时称对象animal是对象tiger的上转型对象
    
  • 上转型对象不能操作子类新增的成员变量,也不能调用新增的方法。但是可以操作继承或隐藏的变量、继承或重写的方法。

  • 重写后,一定是调用了子类重写的实例方法。

  • 将对象的上转型对象强制转换到一个子类对象,这是子类对象又具备子类特有的属性和功能

package com.SubClazz;

class WildMan{
    void cryspeak(String s){
        System.out.println(s);
    }
}

class People extends WildMan{
    void calculate(int a,int b){
        int c=a*b;
        System.out.println(c);
    }
    void cryspeak(String s){
        System.out.println("**"+s+"**");
    }
}

public class Monkey {
    public static void main(String[] args) {
        WildMan monkey;
        People people = new People();
        monkey = people;  //monkey是people的上转型对象
        monkey.cryspeak("I love you");
        //monkey.calculate(1,2);  非法,不能调用子类新增的方法

        People people_1 = (People) monkey; //把上转型对象强制转化成子类的对象
        people_1.calculate(10,10);
    }
}

运行结果:

**I love you**
100

继承与多态

当有多个子类且都重写了某个方法时,上转型对象调用这些方法时会具有多种形态。

Cry.java

package com.SubClazz;

class Animal{
    void cry(){
    };
}

class Dog extends Animal{
    void cry(){
        System.out.println("汪汪");
    }
}

class Cat extends Animal{
    void cry(){
        System.out.println("喵~");
    }
}

public class Cry {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal = new Dog();
        animal.cry();
        animal = new Cat();
        animal.cry();
    }
}

运行结果:

汪汪
喵~

abstract类和方法

  • 定义:用关键字abstract修饰。
  • abstract方法只允许声明,不允许实现,没有方法体。
  • 不允许用final和abstract修饰一个方法和类。
  • 不允许用static修饰抽象方法,抽象方法必须是实例方法。
  • abstract类中可以有abstract方法
  • abstract类不能new对象,如果一个非抽象类是某抽象类的子类,那么它必须重写父类的抽象方法(去掉static修饰),给出方法体。如果是一个抽象类子类,那么可以重写或继承父类的abstract方法。
  • 抽象类声明的对象可以成为其子类对象的上转型对象,调用子类重写的方法,体现具体行为。

Friend.java

package com.SubClazz;

abstract class GirlFriend{
    abstract void speak();
    abstract void cooking();
}

class ChinaGirlFriend extends GirlFriend{
    void speak(){
        System.out.println("你好");
    }
    void cooking(){
        System.out.println("我会做水煮鱼");
    }
}

class ForeignGirlFriend extends GirlFriend{
    void speak(){
        System.out.println("Hello");
    }
    void cooking(){
        System.out.println("I can make cakes");
    }
}

class Boy{
    GirlFriend friend;  //抽象类对象不能new
    //
    void setGirlFriend(GirlFriend f){
        friend = f;
    }
    void showGirlFriend(){
        friend.speak();  //非abstract类中,抽象类的对象调用其重写的方法
        friend.cooking();
    }
}

public class Friend {
    public static void main(String[] args) {
        GirlFriend girl = new ChinaGirlFriend(); //girl是上转型对象
        Boy boy = new Boy();
        boy.setGirlFriend(girl); //
        boy.showGirlFriend();

        girl = new ForeignGirlFriend();
        boy.setGirlFriend(girl);
        boy.showGirlFriend();
    }
}

运行结果:

你好
我会做水煮鱼
Hello
I can make cakes

面向抽象编程

PillarVolume.java

package com.SubClazz;

abstract class Geometry{
    public abstract double getArea();
}

class Pillar{
    Geometry bottom;
    double height;
    Pillar (Geometry bottom,double height){
        this.bottom = bottom;
        this.height = height;
    }
    public double getVolume(){
        if(bottom==null){
            System.out.println("没有底,无法计算体积");
            return -1; //小小bug
        }
        return bottom.getArea()*height;
    }
}

class Circle extends Geometry{
    double r;
    Circle(double r){
        this.r = r;
    }
    public double getArea(){
        return (3.14*r*r);
    }
}

class Rectangle extends Geometry{
    double a,b;
    Rectangle(double a,double b){
        this.a = a;
        this.b = b;
    }
    public double getArea(){
        return a*b;
    }
}

public class PillarVolume {
    public static void main(String[] args) {
        Pillar pillar;
        Geometry bottom = null;
        pillar = new Pillar(bottom,100);  //null底的柱体
        System.out.println("体积"+pillar.getVolume());

        bottom = new Rectangle(12,22);
        pillar = new Pillar(bottom,20);
        System.out.println("体积"+pillar.getVolume());

        bottom = new Circle(10);
        pillar = new Pillar(bottom,10);
        System.out.println("体积"+pillar.getVolume());
    }
}
//自评:abstract类的好处是不需要用上转型对象,也不需要用对象的组合

运行结果:

没有底,无法计算体积
体积-1.0     //小小bug
体积5280.0
体积3140.0

开闭原则

定义:让设计的系统对扩展开放,对修改关闭。

表现为增加模块时无需修改现有模块

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值