面向对象OOP基础(2)

继承关系

定义: Java中继承,需要使用extend关键字;
目的: 简化代码结构,将一类事物的共性提取到父类中,子类直接继承即可,不用再重复的实现相同的功能代码;更改时,直接更改父类一处代码即可,便于维护
Demo
释义:当前有两个类,分别是猫和企鹅;分别的情况如下:

猫:
属性:性别、年龄、名字、声音
方法:无参和全参构造方法,以及属性的获取和设置方法
企鹅
属性:性别、年龄、名字、颜色
方法:无参和全参构造方法,以及属性的获取和设置方法

根据上述实现的代码如下

public class Cat {
    private String gender;//性别

    private int age;//年龄

    private String name;//名字

    private String sound;//声音

    public Cat(){}

    public Cat(String gender, int age, String name, String sound) {
        this.gender = gender;
        this.age = age;
        this.name = name;
        this.sound = sound;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public String getSound() {
        return sound;
    }

    public void setSound(String sound) {
        this.sound = sound;
    }
}

企鹅

public class Penguin{
    private String gender;//性别

    private int age;//年龄

    private String name;//名字

    private String color;//颜色

    //无参构造
    public Penguin() {
    }

    //全参构造
    public Penguin(String gender, int age, String name, String color) {
        this.gender = gender;
        this.age = age;
        this.name = name;
        this.color = color;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

分析:

在上面两个类中,猫、企鹅都对
属性:性别、年龄、名字
进行了重复的定义,还实现了相同的set/get方法,导致代码重复
其次,当我需要新增一个狗的类时,它也是动物,也有性别、年龄、名字属性时,我们还需要重复去实现和定义
结论:我们可以定义一个父类,比如动物,使得其他猫、狗、企鹅等类,在创建时,自动就拥有相同的属性和方法,不用再重新去写了

使用extend后
动物Animal 类

public class Animal {

    private String gender;//性别

    private int age;//积蓄

    private String name;//名字

    public Animal(){}

    public Animal(String gender, int age, String name) {
        this.gender = gender;
        this.age = age;
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

public class Cat extends Animal{

    private String sound;//声音

    public Cat(){}

    public Cat(String gender, int age, String name, String sound) {
        super(gender, age, name);
        this.sound = sound;
    }

    public String getSound() {
        return sound;
    }

    public void setSound(String sound) {
        this.sound = sound;
    }
}

企鹅

java
public class Penguin extends Animal{
    private String color;//颜色

    //无参构造
    public Penguin() {
    }

    //全参构造
    public Penguin(String gender, int age, String name, String color) {
        super(gender, age, name);
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
} 

调研示例:

使用子类给父类的属性进行赋值,以及有参创建对象;

public class test {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.setName("肥妞");

        Cat allCat = new Cat("雌",3,"小名妞妞","喵喵喵");

        System.out.println(cat.getName());
        System.out.println(allCat.getName()+",今年"+allCat.getAge()+"岁");
    }
}

结论1: 上述代码表示,子类继承父类后,可以通过子类使用父类的属性和方法
注意1: Java代码中,只允许单继承,即一个子类只能有一个父类;只能extend一次;
注意2: 当有继承关系时,创建子类对象时,会优先创建对应的父类对象,再创建子类对象;
注意3: 所有的Java类都往上追朔,最后都能追溯到同一个父类,Object.class;这个类是所有的根类或者说超类;

子类继承父类后,不能继承的内容
1.必须是父类私有属性和私有方法(即被private修饰的方法或者属性)不能被继承
2.子类和父类不在同一个包下时,default修饰的内容不能被继承使用
3.构造方法不能被继承,可以被调用

super关键字

1.super是直接父类对象的引用
释义:
A extend B; B extend C
在A中调用super,只能调用到B的属性和方法
2.可通过super来访问父类中被子类覆盖的方法或者属性
释义:
人类是猿猴的一种,猿猴有爬树的技能,人类继承了这种技能,但是与猿猴本身的技能已经不一样了,这个时候作为一个人类调用爬树的技能则使用的是人类自身的方法;如果要使用原始的猿猴的技能,则需要特别的使用super来调用

注意: 当有继承关系,创建子类时,会默认使用super调用父类的构造方法,调用父类无参构造时可以省略不写,要写时super必须放在构造方法的第一行;且不能与this();同时使用

引申 子类在创建对象时,如果不指定父类的构造函数,会默认调用父类的无参构造,所以我们在代码实现时,创建了有参构造,就要求必须创建无参构造;否则子类将找不到父类的无参构造,报错;

重写

场景条件 必须要存在继承关系,当父类中的方法无法满足子类的需求时,可以使用在子类重新实现该继承方法的逻辑,这个过程就是重写;
Demo

由于任何类最终都继承与object类,我们就用Object的toString()方法示例
toString()该方法是获取对象的名字+@+hash码值的16进制表示,简单理解为其名字的字符串即可
创建类OverWrite,区分OverWrite重写和不重写两种情况,调用OverWrite.hashCode()结果来看区别

OverWrite不重写时:

public class OverWrite {
    private String name;
    private String high;
    private int age;
}

调用结果:

public class test {
    public static void main(String[] args) {
        OverWrite overWrite = new OverWrite();
        System.out.println(overWrite.toString());
        //重写前:com.chen.oop.inherit.OverWrite@677327b6
        }
 }

OverWrite重写时:

public class OverWrite {
    private String name;
    private String high;
    private int age;
    @Override
    public String toString(){
        return "重写方法之后,就打印我";
    }
}

调用结果:

public class test {
    public static void main(String[] args) {
        OverWrite overWrite = new OverWrite();
        System.out.println(overWrite.toString());
        //重写后:重写方法之后,就打印我
        }
}

注意事项

1.重写方法必须与被重写方法,有相同的方法名称、参数列表与顺序、和返回类型
2.并且重写方法的访问权限必须大于等于被重写方法
3.重写相当于子类自己重新实现一遍继承到的方法,如果无法被继承,则不能被重写,即不能被@Override标注;
4.特别注意:静态方法可以被继承,但是不能被重写;

抽象类

抽象类–即某些类不具备被实例化的意义,是一类对象的抽象概括,

比如:人、动物、宠物;没有一种动物叫动物即没有实际的对象

1.抽象类使用abstract关键字定义
2.抽象类不能进行实例化,即不能new创建对象
3.抽象类中的某些方法需要子类进行更丰富的实现,父类实现没有意义
则通过abstract关键字修饰,定义为抽象方法,其没有方法体;
4.使用abstract修饰的方法,是抽象方法;
5.抽象类中的方法,不一定是抽象方法;有抽象方法的类,一定是抽象类
6.子类继承抽象类,必须将抽象类中的方法进行实现,或者将子类也定义为抽象类

final

1.final修饰变量,标识变量值不可变
2.final修饰方法,表示方法不可以被重写
3.final修饰类,表示该类不能被继承

Object类

native修饰的方法指的是原生方法,即直接操作系统内核的方法,通常是用C语言写的,也就是JDK中,存在的一些原生方法,是直接调用的C语言等操作系统底层的方法;

1.toString();打印包信息和hasCode处理过的值
2.equals();Object底层实现是==;必须要重写,在java中的String、Integer等都重写了改方法,是直接比较的两个值
==比较的是两个基本类型的值,或者引用类型的地址值;
3.notify();是线程激活的方法
4.wait();是线程等待方法
5.finalize();是jvm中用于判断对象是否还有引用,是否可以回收的方法
6.clone克隆一个对象

多态

定义:调用同一个的方法,由于参数类型一致,但对象的具体实现是不一致的,从而使得程序执行不同的命令
实现多态条件

1.要有继承关系
2.子类方法必须重写父类方法
3.父类引用指向子类对象

Demo
释义:下面有四个类,宠物类-Pet;Dog继承Pet;Cat继承Pet;Person类的对象通过调用宠物类的eat()方法,实现相同的引用,不同的实例对象,执行不同的程序;Pet、Dog分别都对Pet的eat()方法进行重写;
实现方式

1.使用父类作为方法的形参实现多态
2.使用父类作为方法返回值实现多态

Pet

public abstract class Pet {
    public abstract void eat();
}

Dog

public class Dog extends Pet{
    @Override
    public void eat() {
        System.out.println("狗吃东西");
    }
}

Cat

public class Cat extends Pet{
    @Override
    public void eat() {
        System.out.println("猫吃东西");
    }
}

Person

public class Person {
//    public void eat(Dog dog) {
//        dog.eat();
//    }
//
//    public void eat(Cat cat) {
//        cat.eat();
//    }

    public void eat(Pet pet) {
        pet.eat();
    }

    public static void main(String[] args) {
        Person p = new Person();
        Pet dog = new Dog();
        Pet cat = new Cat();
        p.eat(dog);
        p.eat(cat);
    }
}

注意: INSTANCEOF可以用来进行实例对象的类型判断
**多态作用:**为了提高代码的可维护性和可扩展性,方便代码逻辑编写

引用类型转换

当父类需要转换成子类时,需要进行强制转换;但在强制转换前,需要先判断父类引用指向的子类对象;无法确定,将导致运行中报错;判断方式:instanceof
当子类需要向父类转换的时候,直接自动转换,无须进行判断;

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值