第一周预习继承

文章目录

继承

1.1继承定义 

1.2继承格式

1.3继承的好处与弊端

1.4继承使用原则

1.5继承中访问变量的特点

1.6继承中构造方法的访问特点 

1.7继承中成员方法访问的特点 

1.8suppr内存图

1.9方法重写及其注意事项

1.10继承注意事项


继承

 1.1继承定义 

继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及 追加属性和方法(子类可以使用父类中非私有的成员。)

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。

eg:我有动物类,猫类,狗类(首先这些符合is a继承关系)猫类和狗类有相同特征:名字,年龄,要吃食物等。然后我们就可以将这相同特征部分抽象到动物类里面

 下面是实现代码:

  Animal实现了抽象的相同特征,以便子类调用

/**
 * 父类
 */
public class Animal {
    //成员变量
    String name; //动物名字
    int age;     //动物年龄

    //eat方法 成员方法
    public void eat(String food){
        System.out.println("一只"+this.age+"岁的"+this.name+"要吃"+food);
    }

    //构造方法
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //构造方法 空构造,建议加上
    public Animal() {
    }

    //get set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 俩个子类,Cat,Dog

子类的name age相同属性以及eat相同方法共同组成的相同特征在父类实现

/**
 * 子类
 **/
public class Cat extends Animal{

    public void eat(String name,int age,String food){
        Animal animal = new Animal(name,age);
        animal.eat(food);
    }
}
/**
 * 子类
 **/
public class Dog extends Animal{
    public void eat(String name,int age,String food){
        Animal animal = new Animal(name,age);
        animal.eat(food);
    }
}

测试类  创建对象,调用eat方法就能得到下面的结果

/**
    测试方法
 **/
public class Text {
    public static void main(String[] args) {

        Cat cat = new Cat();//Cat对象引用
        //调用eat方法
        cat.eat("Tom猫",2,"鱼");

        System.out.println("----------------------");

        Dog dog = new Dog();//Dog对象引用
        //调用eat方法
        dog.eat("旺财",5,"chouchou");
    }
}
一只2岁的Tom猫要吃鱼
----------------------
一只5岁的旺财要吃chouchou

 看完大致用法,下面就里面细节进行介绍

1.2继承格式

public class 子类名 externs 父类名{}

externs可以理解为扩展,即父类是子类的扩展,子类就可以调用父类的方法 

1.3继承的好处与弊端

好处:提高代码的复用性(创建一个父类存放多个子类相同的部分)

           提高代码的维护性(由于相同的部分移至到一个类里,方便修改)

弊端:继承实现代码的复用,增加了子类与父类之间的耦合性,使得更改父类,子类一定会跟着变化                                                                                                                       ------引用黑马程序员

1.4继承使用原则

要满足is a关系,即A是B的一部分或B是A的一部分时可以考虑使用继承

1.5继承中访问变量的特点

子类方法中访问一个变量

  1. 首先在子类局部范围找
  2. 其次在子类成员范围找
  3. 最后再父类成员范围找(包括父类的父类)
  4. 如果都没有就报错
public class Jicheng{
    public String weight = "50kg";//父类的父类找的变量
}

class Fu extends Jicheng{
    public String height = "170cm";//父类成员找的变量
}
class Zi extends Fu {
    int age = 18;//子类成员范围找的变量
    public void show(){
        String color = "yellow";//子类局部范围找的变量
        System.out.println(height);
        System.out.println(weight);
        System.out.println(age);
        System.out.println(color);
    }

    /**
     * 内部测试类
     * @param args
     */
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.show();
    }
}

 1.6继承中构造方法的访问特点 

子类中的构造方法都会默认在前面加一个supper();  然后就会调用到父类的构造方法;要是想解除,则要在子类构造方法中定义一个显示的有参构造;这个子类就会不调用父类无参构造而调用有参构造;   从这里不难看出,在自己添加有参构造时,最好在加上无参构造;

/**
 * Zi
 * @author 祥瑞
 */
public class Zi extends Fu{
    int age;
    public Zi(){
        System.out.println("Zi类无参构造");
    }

    public Zi(int age) {
        this.age = age;
        System.out.println("Zi类有参构造");
    }
}


/**
 * Fu
 * @author 祥瑞
 */
public class Fu {
    int age;
    public Fu(){
        System.out.println("Fu类无参构造");
    }

    public Fu(int age) {
        this.age = age;
        System.out.println("Fu类有参构造");
    }
}


public class Demo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        Zi zi2 = new Zi(18);
    }
}

运行结果(原因如上)

Fu类无参构造
Zi类无参构造
Fu类无参构造
Zi类有参构造

1.7继承中成员方法访问的特点 

和成员变量访问特点差不多,访问成员方法时,也是先从子类里找成员方法,没有再去父类找,再没有的话就报错

1.8suppr内存图

/**
 * Zi
 * @author 祥瑞
 */
public class Zi extends Fu{
    int age = 30;
    public void method(){
        int age = 20;
        System.out.println("Zi类ziMethod方法");
        System.out.println(age);
        System.out.println(this.age);
        System.out.println(super.age);
    }
}

/**
 * Fu
 * @author 祥瑞
 */
public class Fu {
    int age = 40;
    public void show(){
        System.out.println("Fu类show方法");
    }
}

public class Demo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.method();
        zi.show();
    }
}

 运行结果:

Zi类ziMethod方法
20
30
40
Fu类show方法

 下面详细介绍机器堆栈的运行情况

 运行到public static void main(String[] args)这句时情况如下,main方法进入栈中

 运行到 Zi zi = new Zi(); 时,先把zi动作加载到main方法里面,然后是在堆中创建一个内存,情况图如下:

 但是子类构造方法会默认访问父类的构造方法,然后就进入到父类中,存放了父类的age,如图:

运行到 zi.method(); 时,method方法会进入栈内存中,如图

此时输出的

age = 20

this.age = 30              直接找this的地址

supper.age = 40         先找Zi的地址,然后找到supper空间

运行到 zi.show(); 时,就会在栈中弹出method方法,然后show方法进入栈内存,由于Zi里面没有,然后就会从Fu里找,最后存到栈中的是Fu的show方法,如图所示

最后依次弹出show方法和main方法。展示结束 

1.9方法重写及其注意事项

优点:方法重写可以既包含父类的内容,还可以添加子类自己独特的内容;

注意事项:子类重写的方法的访问权限要高于父类,父类的私有方法不可以被重写,可以用@Override注释进行验证。

1.10继承注意事项

java支持单继承,可以多层继承;

即一个类只可以继承一个类,但父类还可以继承别的类;

拓展:java接口可以实现多实现在以后碰到选择继承还是实现时,一般选择实现接口,因为实现可以多实现,没有单继承这方面的限制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G ♡ Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值