java三大特性-2-继承

继承

static关键字 

static (特殊修饰符)是用来修饰类、方法(静态方法)、成员变量(静态变量)、代码块(静态代码块)。

成员变量和类变量(static 修饰的成员变量)区别:

  • 成员变量又被成为对象变量/实例变量,它是随着对象的创建而产生的,对象之间互不影响。
  1.         成员变量是通过对象名.属性名来进行访问和操作
  • 类变量(静态变量),它是随着类的加载而产生的,被该类所有的对象所共享。
  1.         类变量是通过类名.属性名来进行访问和操作(当然也可以采用对象名.类变量名来访问,但不建议) 

// 类变量建议采用类名.属性名方式使用

类名.属性名 

 成员方法和静态方法区别:

  • 在同一类中,成员方法之间可以直接互相调用,也可以调用静态方法。

                成员方法可以直接使用成员变量,也可以直接使用静态变量。

  • 在同一个类中,静态方法之间可以直接互相调用,但不可以调用成员方法。

                静态方法可以直接使用静态变量,但不可以使用成员变量。 

 代码块/非静态代码块/成员代码块/构造代码块和静态代码块区别:

public class 类名 {
    // 代码块:用语存储一些希望在构造方法执行前执行的程序段
    // 总是在构造方法执行前
    {
        // 若干代码
        // 若干程序段
    }

    // 静态代码块:用于存储一些希望在类加载时只执行依次的程序段
    // 类加载时执行,且只执行一次
    static {
        // 程序段
    }
}

 (同一个类中)执行顺序:静态代码块(类加载的时候只执行一次)-> 代码块(创建对象 一次就执行一次,在构造方法前执行)-> 构造方法(创建对象一次就执行一次)

(创建子类)执行顺序:父类的静态代码块 -> 子类的静态代码块 -> 父类的代码块 -> 父类的构造方法 -> 子类的代码块 -> 子类的构造方法

 注意:(暂时可以用它解决的问题)

1.一些工具类的方法,可以定义为静态的,这样不需要创建对象就可以使用。

2.有一些内容需要被多个对象共享,就可以将这些内容定义静态的。

3.再类加载时,希望执行一些代码段,可以将其定义在静态代码块中。

4. ....

继承的概述

继承是 Java 中实现代码重用的重要手段之一也是面向对象的三大特性之一。在继承这一概念中,会引申出“父类”(superclass)和“子类”/“派生类”(subclass),就像现实生活中的父子一样,子女是父辈的继承人,可以继承父辈的财产。

在父类中定义子类共有的信息(变量、方法),子类只需要继承父类就可以拥有这些内容,已达到重用的目的。(提升扩展性)

继承的使用

 不是看到重复地代码段就考虑继承,也要结合当前场景。

场景需要符合一个 子类 is a 父类 的关系。

例如:现有狗类和猫类,在它们中拥有很多共有的信息,这时候就可以抽取狗类和猫类的共有信息到父类(宠物类)。

狗类 is a 宠物类

猫类 is a 宠物类

不能胡乱使用继承,要和生活中的实际保持一致!例如:现有一学生类,也拥有狗类或猫类相似的属性和行为,不能将其也归属于宠物类子类。


 1.先定义父类(将子类共有的信息:属性、方法定义到父类中)

public class 父类名{
    // 共有属性

    // 共有方法

}

2.定义子类(给子类继承好相应的父类)

extends:继承

public class 子类名 extends 父类名{
    
}

在 Java 中继承是单根继承,如果已经继承了一个类,就不能在继承其他的类。继承还有一个传递性。

联想记忆:你只能有一个亲爹,你爷爷的财产可以由你爸爸继承,你爸爸的财产由你继承。

 super关键字

联想 this 关键字。

this:代词,当前类的一个对象。

  • this.自身的属性
  • this.自身的方法
  • this(构造参数) 调用自身的构造方法

super:代词,当前类的父类的一个对象。 

  • super.父类的属性   调用父类的信息是会受到访问权限修饰符的影响。无法调用父类私有的内容。
  • super.父类的方法
  • super(构造参数)   调用父类的构造方法

 在调用子类的构造方法时,无论是带参还是无参,都会先默认调用父类的构造方法。

调用父类构造一定是写在子类的构造方法的有效代码的第一行。

protected 访问权限修饰符

本类中、同包的不同类中、不同包的子类中。

修饰符/访问范围本类中同一个包的不同类中不同包的子类中本项目中
private(私有的)fire
默认的(包级的)firefire
protected(受保护的)firefirefire
public(公共的)firefirefirefire

方法重写(Override)

方法重写是发生在有继承关系的前提下。 

方法重写的概述

 在子类继承了父类的方法后,如果父类的方法无法满足子类的要求,子类可以对继承过来的方法进行重写!重写后,执行时,会执行该方法。

方法重写的使用 

 子类对父类的方法进行重写:

1.继承来的

        子类也不是能继承所有父类的内容

  •                 父类私有的内容,无法被子类继承
  •                 父类和子类不再同一个包时,默认修饰(包级)的内容,无法被子类继承
  •                 父类的构造方法,无法被子类继承

2.方法名和父类的方法名要一致 

3.方法参数和父类方法参数要一致

4.方法返回值类型和父类方法返回值类型要一致

5.方法的访问修饰符和父类的访问修饰符要一致,或范围更大(不能严于父类方法)。

        父类方法: void test() {}

        子类重写方法: private void test() {}     (错误)

6.方法的抛出的异常类型和父类方法跑出的异常类型一致,或范围小或类型少(不能抛出比父类更多更大的异常类型)

可以使用 @Override 注释(Annotation) /注释,来标注重写的方法,可以帮助你在编译期检查该方法是否是正常的重写。


两种方法来实现方法重写: 

  1. 完全覆盖父类方法的内容
  2. 对父类方法进行增强 
  •                 使用 super 关键字调用父类的方法 

方法重写和重载的区别 

方法重载:Overload 

  • 在同一个类中,多个方法的 方法名相同,参数列表不同(类型不同、顺序不同、个数不同)的情况,被称为方法的重载。方法重载和返回值类型、访问权限修饰符等无关。 
  • 通过相同的方法,实现对不同类型数据的处理。

方法重写:Override

  •  在子类中,与父类的方法名相同,参数列表相同,返回值类型相同,访问权限修饰符不严于父类,跑出的异常类型不多于或大于父类方法的情况,被称为方法的重写。
  • 方法重写是为了增强继承过来的父类的方法。

Object类 

java.lang.Object:祖宗类

java 中所有的类都是直接或间接继承自 Object 类,不写默认就是继承自 Object 类。

在 Object 类中定义了一系列的方法,这些方法被所有类继承。 

  • toString():String 将对象转换为字符串
// demo09.Pet@15db9742
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

在我们之前输出对象引用时,输出的是像 demo09.Pet@15db9742 内容,原因就是因为输出方法,在方法内调用了对象的 toString() 方法,把对象转换为字符串。

如果你想在输出对象时,输出对象的特征信息而不是哈希值等,在类中重写 Object 类的toString() 方法。

  • equals(Object obj):boolean 判断两个对象是否相等
public boolean equals(Object obj) {
    return (this == obj);
}

String 类重写 equals() 方法:

public boolean equals(Object anObject) {
    // == 比较引用数据类型,比较地址值,地址值一致说明是同一个对象
    if (this == anObject) {
        // 同一个对象不需要比较,肯定相同
        return true;
    }
    
    // 判断要比较的是不是 String 类型
    // 如果不是 String 类型没必要比较了
    if (anObject instanceof String) {
        // 将要比较的内容转换为字符串类型
        String anotherString = (String)anObject;
        // 获取两个字符串的长度,判断字符串长度是否一致,不一致也没必要比较了
        int n = value.length;
        if (n == anotherString.value.length) {
            // 两个字符数组,1个下标1个下标的去比较字符,只要有一个字符不一致,立马返回false
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

 如果以后我们要比较两个对象内容是否相同,也可以模仿 String 实现重写 equals() 方法。

  • ...

 equals和==的区别

 如果是基本数据类型,== 可以用来比较两者的内容是否相同。

如果是引用数据类型,== 比较的是两者的地址值是否相同(如果地址值相同,代表室同一个对象)。

int num1 = 10;
int num2 = 10;
boolean flag = (num1 == num2); // true

equals() 方法是定义在 Object 类中的,默认是使用 == 来比较两者是否相同,所以它比较的是两者的地址值。如果你想比较两者的内容是否一致,可以模仿 String 的做法,String 对继承来的equals() 方法进行了方法重写。

近期常用快捷键:

封装:Alt + Shift + S -> R -> Alt + A -> Alt R

无参构造:Alt + Shift + S -> C -> 回车

有参构造:Alt + Shift + S -> O -> 回车

toString():Alt + Shift + S -> H -> 回车  -----> 展示类的信息(在输出时就不会出现哈希值)

equals():Alt + Shift + S -> S -> 回车    ------> 判断类与类相等时,需要重写 Object 判断,重写后就可以判断内容了,不重写就会默认使用 Object 的equals方法(== 比较地址)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值