java零基础入门学习第七天——相关笔记

继承

继承的概念:泛指把前人的作风、文化、知识、财产等接受过来

Java中的继承

让类与类之间的产生父子关系

​ 被继承的类叫做父类(基类,超类)

​ 继承的类叫做子类(派生类)

格式(extends)

​ class 父类 {

​ //……

​ }

​ class 子类 extends 父类 {

​ //……

​ }

子类继承父类:子类拥有了父类的非私有成员(成员变量、成员方法)

package study2.demo;

public class Parent {
    private String name;
    private int age;

//    快捷键:alt+insert,快速成成构造方法(Constructor)和setXxx()和getXxx()方法(Getter and setter)
//    构造方法

    public Parent() {
    }

    public Parent(String name, int age) {
        this.name = name;
        this.age = age;
    }
//setXxx()和getXxx()方法
    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;
    }
}
package study2.demo;
/*
    Child:子类,派生类
    Parent:父类,基类,超类
 */
public class Child extends Parent {

}
package study2.demo;
//测试类
public class Test {
//    main函数是程序的主入口,所有的代码都是从这里开始执行的
    public static void main(String[] args) {
//        创建Child类的对象
        Child c = new Child();
//        给对象的姓名设置为张三
        c.setName("张三");
        c.setAge(30);
//        c.name="张三";          这个报错的原因是这是父类的私有成员(private修饰)
        System.out.println("他的名字是:"+c.getName());
        System.out.println("他的年龄是:"+c.getAge());
/*
    java中,子类只能继承父类的非私有成员(成员变量、成员方法,由public修饰的)
 */
    }
}
继承的使用场景

多个类中存在相同的属性和行为时,可以将这些内容提取出来放到一个新类中,让这些类和新类产生父子关系,实现代码复用

案例:定义继承关系的动物类并使用

需求:分别定义Dog类、Pig类,他们共有的属性有:name,age,sex,共有的行为有:eat()。两者特有的行为分别是:watch(),snore()

不用继承

package study2.demo;
//定义一个dog类
public class Dog {
    private String name;
    private int age;
    private String sex;

    public Dog() {
    }

    public Dog(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    //    共有的行为
    public void eat() {
        System.out.println("我们都会吃饭");
    }

    //    Dog类特有的行为
    public void watch() {
        System.out.println("Dog类特有的行为");
    }

}
package study2.demo;
//定义一个pig类
public class Pig {
    private String name;
    private int age;
    private String sex;

    public Pig() {
    }

    public Pig(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    //    共有的行为
    public void eat() {
        System.out.println("我们都会吃饭");
    }

    public void snore() {
        System.out.println("Pig类特有的行为");
    }
}
package study2.demo;
/*
    需求:
    分别定义Dog类、Pig类
    它们共有的属性有name,age,sex
    两者特有的行为分别是:watch(),snore()

    解决方案
    方案一:传统代码(不是有继承)
    方案二:使用继承后的代码
 */
public class TestAnimal {
    public static void main(String[] args) {
//        测试狗类
        Dog d = new Dog();
        d.eat();
        d.watch();
        System.out.println("————————————");

//        测试猪类
        Pig p = new Pig();
        p.eat();
        p.snore();

    }
}

使用继承

package study2.demo;
//定义一个dog类
public class Dog extends Animal {

    //    Dog类特有的行为
    public void watch() {
        System.out.println("Dog类特有的行为");
    }

}
package study2.demo;
//定义一个pig类
public class Pig extends Animal {

    public void snore() {
        System.out.println("Pig类特有的行为");
    }
}
package study2.demo;
//定义一个父类
public class Animal {
    private String name;
    private int age;
    private String sex;
//无参
    public Animal() {
    }
//全参
    public Animal(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
//    setXxx(),getXxx()

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
    public void eat() {
        System.out.println("我们都会吃饭");
    }
}
package study2.demo;
/*
    需求:
    分别定义Dog类、Pig类
    它们共有的属性有name,age,sex
    两者特有的行为分别是:watch(),snore()

    解决方案
    方案一:传统代码(不是有继承)
    方案二:使用继承后的代码
 */
public class TestAnimal {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.eat();
        d.watch();
        System.out.println("——————————");

        Pig p = new Pig();
        p.snore();
        p.eat();
    }
}

继承的优点:

1.功能复用:直接将已有的属性和行为继承过来,实现了功能的复用,节省了大量的工作

2.便于扩展新功能:在已有功能的基础上,更容易建立,扩充新功能

3.结构清晰,简化认识:同属于一个继承体系的相关类,他们之间结构层次清晰,简化了人们对代码结构的认识

4.易维护性:不同类之间的继承关系,让这些事物之间保持一定程度的一致性,大大降低了维护成本

继承的缺点:

1.打破了封装性:父类向子类暴露了实现细节,打破了父类对象的封装性

2.高耦合性:类与类之间紧密的结合在一起,相互依赖性高

程序设计的追求

低耦合,高内聚

耦合:两个(或更多)模块相互依赖对方

内聚:模块内部结构紧密,独立性强

继承关系中类成员的使用
继承关系中子父类成员变量的使用

需求:子父类中定义了同名的成员变量,如何使用

package study2.demo;
//父类,苹果类
public class Fruit {
//    成员变量
    int price = 20;
}
package study2.demo;
//子类,苹果类
public class Apple extends Fruit {
//    成员变量
    int price = 10;

    public void showPrice() {
//        局部变量
        int price = 5;
        System.out.println(price);      //5
        System.out.println(this.price);      //10   this在本类找
        System.out.println(super.price);      //15  super在父类找
    }
}
package study2.demo;

public class Test2 {
    public static void main(String[] args) {
//        需求:测试继承关系中,子父类间成员变量的使用
        Apple a = new Apple();
        a.showPrice();
/*
    Java中使用变量的规则
        遵循“就近原则”,局部位置有就使用,
        没有就去本类的成员位置找,有就使用
        没有就去父类的成员位置找,有就使用,没有就报错
 */
    }
}

Java中使用变量的规则:
遵循“就近原则”,局部位置有就使用,
没有就去本类的成员位置找,有就使用
没有就去父类的成员位置找,有就使用,没有就报错

继承关系中成员变量使用结论

查找变量的原则:就近原则

查找变量的顺序:局部变量—>成员变量—>父类—>更高的父类……Object

访问父类变量的方式:super.父类变量名;

super:当前对象父类的引用(父类内存空间的标识)

对象初始化顺序:先初始化父类内容,再初始化子类内容

this和super的区别

this

本质:对象;

用法:从本类开始找

super

本质:父类内存空间的标识

用法:从父类开始找

区别

​ 直接写变量名: 局部变量
​ this.成员变量名: 本类的成员变量
​ super.成员变量名: 父类的成员变量名

package study2.demo;
//父类
public class Fu {
    int num = 30;
}
package study2.demo;
//子类
public class Zi extends Fu {
    int num = 20;
    public void show() {
        int num = 10;

        System.out.println(num);       //10
        System.out.println(this.num);       //20
        System.out.println(super.num);       //30

    }
}
package study2.demo;

public class Test3 {
    public static void main(String[] args) {
        /*
            遵循“就近原则”
            先在局部位置找,有就使用
            没有就去本类的成员位置找,有就使用
            没有就去父类的成员位置找,有就使用,没有就报错

            如果局部变量,本类的成员变量,父类的成员变量重名了,如何解决?
            直接写变量名:     局部变量
            this.成员变量名:     本类的成员变量
            super.成员变量名:    父类的成员变量名
         */
        Zi z = new Zi();
        z.show();
    }
}
继承关系中子父类成员方法的使用

需求:子父类中定义了同名的成员方法,如何使用

package study3.demo;
//父类,武功类
public class Martial {
//    练习内功
    public void internalStrength() {
        System.out.println("练习内功");
    }
//    练习招式
    public void stroke() {
        System.out.println("练习招式");
    }
}
package study3.demo;

public class NineYin extends Martial {
    //    练习内功
    public void internalStrength() {
//        这里是在调用父类的成员方法
        super.internalStrength();
        System.out.println("以柔克刚");
    }
    //    练习招式
    public void stroke() {
        System.out.println("九阴白骨爪");
    }
}
package study3.demo;
/*
    需求:
    定义武功类Martial:
        练习内功:internalStrength()
        练习招式:stroke()
    定义九阴真经类NineYin,继承Martial类
        练习内功:internalStrength()
        练习招式:stroke()
    九阴真经的修炼,不仅要练习基本内功,还要能够以柔克刚,需要扩展父类方法
    简单的招式已经不足为用,必须有九阴白骨爪这样的大招才能制胜,需要重新实现父类方法
 */
public class Test {
    public static void main(String[] args) {
//        需求:调用NineYin类中的功能
        NineYin ny = new NineYin();
        ny.internalStrength();
        ny.stroke();
    }
}

继承关系中成员方法使用结论

查找方法的原则:就近原则

查找方法的顺序:本类—>父类—>更高的父类……Object

访问父类方法的方式:super.父类方法名();

定义重名方法的前提:父类功能不能完全满足现实需求,扩展父类功能;父类功能已过时,重新实现父类功能

继承关系中子父类构造方法的使用

需求:创建对象时,构造方法是如何被调用的?

需求:父类不存在默认无参构造方法怎么办(须手动调用父类其他构造)

package study3.demo;
//父类
public class Person {
    public Person(String name) {
//        System.out.println("Person的空参构造");
        System.out.println("Person类的带参构造"+name);
    }
}
package study3.demo;
//子类
public class Worker extends Person {
    public Worker() {
        super("A");        //用于初始化父类成员的,必须写在第一行
        System.out.println("Worker的空参构造");
    }
}
package study3.demo;
/*
    测试类:用来演示构造方法的调用的
    结论:子类所有构造方法的第一行都有一个默认的super()用来访问父类的无参构造方法
    如果父类没有无参构造,可以通过super(参数)的形式访问父类的带参构造,
 */
public class Test2 {
    public static void main(String[] args) {
        Worker w = new Worker();
    }
}

结论:创建子类对象时,优先调用父类构造方法;子类构造方法的第一行,隐含语句super(),用于调用父类的默认无参构造

结论:子类所有构造方法的第一行都有一个默认的**super()用来访问父类的无参构造方法;如果父类没有无参构造,可以通过super(参数)**的形式访问父类的带参构造,

方法重写(Override)

定义:子类中出现和父类方法定义相同的方法的现象

解释:方法重写也叫方法的复写、覆盖方法名、参数列表、返回值类型都相同

注意事项:

父类私有方法无法重写;

子类方法访问权限不能小于父类方法;

子类不能比父类方法抛出更大的异常(了解);

四大权限修饰的修饰范围从小到大分别是:
private>默认(什么都不写就是默认)>protected>public

使用场景:

扩展父类功能;父类功能过时,重新实现父类功能

package study3.demo;
/*
四大权限访问修饰符:
     	  本类 同包下的类  不同包下的子类  不同包下的无关类 private:  Y      N        N                 N
默认:      Y     Y         N                 N
protected: Y     Y         Y                 N
public:   Y      Y         Y                 Y
          结论:
          private:强调的是给自己来使用
          默认:强调的是给同包下的类来使用
          protected:强调的是给子类使用
          public:强调的是给大家使用
 */
public class Father {
    private void show1() {
        System.out.println("show private");
    }
    void show2() {
        System.out.println("show 默认");
    }
    protected void show3() {
        System.out.println("show protected");
    }
    public void show4() {
        System.out.println("show public");
    }

    public static void main(String[] args) {
        Father f = new Father();
        f.show1();
        f.show2();
        f.show3();
        f.show4();
    }
}
package study2.demo;

import study3.demo.Father;

public class Son extends Father {
    public static void main(String[] args) {
        Father f = new Father();
//        f.show1();    报错
//        f.show2();        报错
//        f.show3();        报错
        f.show4();

        System.out.println("————————");
        Son s = new Son();
        //        f.show1();    报错
//        f.show2();        报错
        s.show3();
        s.show4();
    }
}
package study3.demo;

public class Test3 {
    public static void main(String[] args) {
        Father f = new Father();
//        f.show1();          //报错
        f.show2();
        f.show3();
        f.show4();
    }
}
package study3.demo;

public class Son extends Father {
    public static void main(String[] args) {
        Father f = new Father();
//        f.show1();		报错
        f.show2();
        f.show3();
        f.show4();
        System.out.println("——————————");

        Son s = new Son();
        s.show2();
        s.show3();
        s.show4();
    }
}

结论:
private:强调的是给自己来使用
默认:强调的是给同包下的类来使用
protected:强调的是给子类使用
public:强调的是给大家使用

方法重写和方法重载的区别:

重载(Overload):

方法名:相同

参数列表:不同(个数或对应的位置类型)

返回值类型:无关

修饰符:无关

定义位置:同一个类

重写(Override):

方法名:相同

参数列表:相同

返回值类型:相同

修饰符:访问权限不小于被重写方法

定义位置:子父类中

Java中继承的特点

1.单继承:Java只支持类的单继承(只能继承一个类),但是支持多层(重)继承(爷爷—>爸爸—>儿子,1对n);Java支持接口的多继承,语法为:接口A extends 接口B,接口C,接口D……

2.私有成员不能继承:只能继承父类的非私有成员(成员变量,成员方法)

3.构造方法不能继承:构造方法用于初始化本类对象;创建子类对象时,需要调用父类构造初始化该对象的父类内容,若父类构造可以被继承,该操作会造成调用的混乱。

4.继承体现了“is a”的关系:子类符合“is a(是一个,比如:红富士苹果(子类)是一个苹果(父类))”父类的情况下,才使用继承,其他情况不建议使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值