(七)面向对象继承,覆盖,抽象类的概括

面向对象(二)

1.this关键字
2.继承思想
3.方法覆盖
4.抽象方法和抽象类
5.Object中的常用方法


this关键字

成员变量与方法内部的变量重名时,会产生成员变量与局部变量的二义性这时候我们可以使用this

this 关键字用来表示当前对象本身,或当前类的一个实例

使用 this.变量名 的语法,此时访问的就是成员变量


作用域链:

作用域链:{}形成作用域,作用域可以嵌套,内层作用域可以访问外层作用域的变量
当在作用域中访问一个变量var,首先在自身作用域中找该变量var,如果自身作用域能找到,不继续向上一层找;
如果在本层没有找到,继续向上一层找,该层没有,继续向其上一层找,查找的过程形成一条链,这个链称为作用域链(scope chain)

public class Person {
   private String name; //变量名被私有化
    private int age;

    public void rest(){
        System.out.println(name+"正在咕噜咕噜");
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age <0 ||age>150){
            System.out.println("年龄不合法");
        }else{
            this.age = age;
        }
    }

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        setAge(age);
    }
}


构造器和setter方法的选用

构造器和setter方法都可以给对象设置数据:

  • 构造器,在创建对象的时候设置初始数据,只能初始化一次。

  • setter方法,创建对象后再设置初始数据,可以设置多次


继承思想

当多个类存在大量相同代码时,我们可以将其相同的特性与行为抽出,放到一个类中,让他们都继承这个类.可以解决多个类存在共同代码的问题

语法: 如果一个类需要继承另一个类,需要使用到extends关键字

public class 子类名 extends 父类名{
}

概念:

  • 被继承的类,称为父类
  • 继承父类的类,称为子类
  • 父类:存放多个子类共有的字段和方法
  • 子类:存放自己特有的字段与方法
  • Object类是Java语言的根类,任何类都是Object的子类,要么是直接子类,要么是间接子类
子类可以直接继承父类的非私有成员,但构造方法除外 


java类继承的特性

  1. 单根型.只支持单继承,一个类只能有一个直接父类(一个孩子只能有一个爹),但支持多重继承
  2. 传递性. C extends B ,B extends A ,C也具备A的特征和行为


访问修饰符判断

子类继承父类之后,可以拥有到父类的某一些成员(字段和方法),根据访问修饰符来判断:

在java中,存在4中修饰符,这4种修饰符用于控制java中 成员变量, 成员方法, 构造方法, 类, 接口等访问权限

修饰符类内部同包子类,同包其他类不同包子类不同包其他类
private
默认
protected
public
  1. private:私有的,只能本类可见默认:
  2. 没有关键字,包访问权限,同包可见
  3. protected:受保护的.①同包可见 ,②子类可见
  4. public:公共的,都可见
  5. 父类的构造器,子类也不能继承,因为构造器必须和当前的类名相同
  6. 访问权限大小:private < 默认< protected< public

继承在实战中的应用

1.两个类在现实中没有关系,但抽象的过程中发现他们有共同的特征和行为,提取公共成员形成父类
2.现实生活中,他们有继承关系,反应到现实中就是 is a关系 学生类 is a 人类


继承的操作

Person类(父类)

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

    public void rest(){
        System.out.println(name+"正在咕噜咕噜");
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if (age <0 ||age>150){
            System.out.println("年龄不合法");
        }else{
            this.age = age;
        }
    }

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        setAge(age);
    }
}

Teacher类(子类)

public class Teacher extends Person {
    //定义自身特有的字段和方法
    private int level;

    public void teach(String aClass){
        System.out.println(getName() +"正在教:"+aClass);
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public Teacher(String name, int age, int level) {
        setName(name);
        setAge(age);
        setLevel(level);
    }
    public Teacher() {
    }
}

测试类

public class Test01Extends {
    public static void main(String[] args) {
        //创建对象
        Teacher t1 = new Teacher();
        //设置名字,从父类中调取的setter方法
        t1.setName("小月");
        //设置年龄
        t1.setAge(18);
        //子类teacher所自定义的字段
        t1.setLevel = 100;
        //调用父类中的方法
        t1.rest();
        t1.teach("英语");
    }
}


方法覆盖


重写/覆盖(overwrite/overrides)

当子类从父类继承过来的方法不能满足自身需要时,子类可以选择重写/覆盖父类的同名方法


方法调用顺序

对象调用方法时,首先在子类查找,子类存在则执行子类,如果没有对应方法再去父类寻找,父类也没有就会报错


方法覆盖细节

  1. 方法重写建立在继承的基础上 所有private修饰的方法不能被重写
  2. 实例方法签名必须相同 (方法签名= 方法名 + 方法的参数列表)
  3. 子类方法的返回值类型是和父类方法的返回类型相同或者是其子类
  4. 子类方法中声明抛出的异常小于或等于父类方法声明抛出异常类型
  5. 子类方法的访问权限比父类方法访问权限更大或相等

重写与实现

重写与实现implements(父类没有实现的方法,子类去实现了,实现是一种特殊的重写)

重写和实现的区别:

  1. 子类继承父类的方法时不能满足自身需求,子类可以选择重写父类的同名方法,这个同名的方法在父类中是实现过的,只不过不能满足子类需求,这个过程叫做重写(override/overwrite)
  2. 子类继承父类的抽象方法时,必须重写父类的抽象方法,这个过程称为实现(implement),因为父类中的方法是抽象的,没有方法体,父类重来就没有实现过这个方法


super关键字

当子类覆盖了覆盖的方法,而我们又想调用父类的方法时,我们可以使用super关键字

后续补充


抽象方法和抽象类


抽象方法

abstract修饰,该方法没有方法体,要求子类必须覆盖该方法我们称为抽象方法

public abstract 返回类型 方法名(参数);

抽象类

使用abstract修饰的类,称为抽象类

public abstract class 类名{
    
}
一般的,抽象类以Abstract作为类名前缀

特点:

  • 抽象类不能创建对象不能实例化),抽象类可以阻止实例化
  • 抽象类中不一定只有抽象方法,可以有普通方法,但是有抽象方法的类,一定是抽象类
  • 一个类继承抽象父类,必须实现抽象父类中的所有抽象方法,除非该类也是抽象类


Object类的常用方法

Object类是java中的根类,本身表示对象的意思

所有类都是Object类的子类,所有所有类的对象都可以调用Object类中的方法


这里讲Object中的equals方法与toString方法

boolean equals(Object obj):拿当前调用该方法的对象和参数obj做比较

String toString():表示把对象中的字段信息转换为字符串格式,打印对象时其实打印的就是对象的toString方法


equals

在Object类中的equals方法和“ == ”符号相同都是比较对象是否是同一个的存储地址

== 符号到底比较的是什么:

  • 比较基本数据类型:比较两个值是否相等
  • 比较对象数据类型:比较两个对象是否是同一块内存空间 每一次使用new关键字,都表示在堆中创建一块新的内存空间
每个类都应该覆盖equals方法去比较我们关心的数据,而不是内存地址,
实际开发过程中,如果两个不同地址的对象持有的数据相同(关键字段,例如学号),
我们称这两个对象业务上相等


重写toString方法

IDEA可以帮助我们重写,当然我们也可以自己重写

 //字段    
   private String name;
    private int age;

@Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


重写equals方法

重写完后,比较的就是对象的数据业务是否相同了

 @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (age != person.age) return false;
        return name != null ? name.equals(person.name) : person.name == null;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值