【Java基础|第十四篇】面向对象基础(四)——继承(二)权限修饰符、重写、final关键字

目录

5、继承

(6)权限修饰符:

        概述:

         范围(从小到大):

         具体范围介绍:

(7)重写:

为什么要重写?

重写的各个要求以及与重载的对比:

注意事项:

toString的重写:

(8)final关键字:

    定义:

用法:


(四)面向对象

5、继承
(6)权限修饰符:
        概述:

        对象中的属性和方法,可以根据不同的权限修饰符来控制访问。

         范围(从小到大):

         public > protected > 默认(default) > private

         具体范围介绍:

public:公共的,类内部,类外部都可以访问。

        用处:比如封装时用于提供对外的公共访问方式。

                   继承时允许被继承的成员是public型

protected:受保护的,同一个类中,同一个包中的子类或其他类,不同包中的子类可以访问

default:默认权限修饰符,指不显式指出修饰符时,就是什么都不写的时候,默认是default型,同一个类,同一个包中的子类和其他类可以访问

private:私有的,仅仅允许同一个类中的访问。

        用处:封装时,将不需要的成员私有化

(7)重写:
为什么要重写?

父子类继承关系中,当子类需要父类的功能,而继承的方法不能完全满足子类的需求,子类里面有特殊的功能,此时可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

重写的各个要求以及与重载的对比:

1、使用前提 重写:父子类继承关系中

                     重载:在同一个类中

2、权限修饰符 重写:重写方法的访问权限修饰符可以被扩大,但是不能被缩小

                                        public > protected > default > private

                         重载:与权限修饰符无关

3、返回值类型 重写:方法的返回类型可以相同,也可以不同(暂时先按相同处理,后续再补充)

                         重载:与返回值类型无关

4、方法名 重写:子类新增方法,和从父类继承的方法,方法名完全相同

                 重载:方法名必须相同

5、参数列表 重写:两个方法的参数列表完全相同

                     重载:参数列表不同(个数或数据类型不同)

6、异常处理范围 重写:方法抛出异常类型的范围可以被缩小,但是不能被扩大(超纲内容,暂时先忽略)

                            重载:不关心这个,变大变小都可以

7、注解:重写要加注解@Override

                这个注解是用来标识该方法是重写的方法,辅助编译器检查,编译器可以直接判断写法是否符合规范

                这个注解不写也是可以的,编译器会先判断他是否有尝试重写的意图,之后再判断是否符合规范。

注意:一般情况下,子类进行方法重写时,最好方法的声明完全一致 

注意事项:

1、子类继承父类,在调用方法的时候,如果子类没有重写,则调用父类方法;如果子类进行了重写,则优先调用子类的方法

2、子类中特有的方法,方法名与父类的方法名必须不同,只要相同,编译器就认为是在尝试重写,按照重写的要求来判断,从而发生编译报错。

3、子类中特有的属性,与父类具有相同的属性时,会隐藏父类。

4、特殊情况:父类中private成员不可以被重写

                        父类中static成员不可以被重写

                        父类中final成员不可以被重写

案例:

//定义父类:员工
class Employee {
    //工号、姓名
    private String id;
    private String name;
    public Employee() {}
    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public void doWork() {
        System.out.println("员工开始工作...");
    }
}



//定义子类:程序员
class Programmer extends Employee {
    //等级:初级、中级、高级、资深
    private String grade;
    public Programmer() {
        //默认会调用父类无参构造器
        //super();
    }
    public Programmer(String id,String name,String grade) {
        //显式调用父类构造器
        super(id,name);
        this.grade = grade;
    }
    //重写方法
    // @Override是注解,用于标识该方法为重写的方法,大家可以不用管
    @Override
    public void doWork() {
        //super.doWork();
        System.out.println("我是程序员,级别为" + grade + ", 开始工作:写代码");
    }
}


//定义子类:经理
class Manager extends Employee {
    //奖金
    private double bonus;
    public Manager() {
        super();
    }
    public Manager(String id,String name,double bonus) {
        super(id,name);
        this.bonus = bonus;
    }
    //重写方法
    @Override
    public void doWork() {
        System.out.println("我是经理,有津贴" + bonus + ", 开始工作:安排部门员工任务");
    }
}

 测试类:

//测试类
public class Test06_Override {
    public static void main(String[] args) {
        //父类对象 调用 doWork方法
        Employee e = new Employee("008", "larry");
        e.doWork();
        System.out.println("------------");
        //程序员子类对象 调用 重写方法
        Programmer p = new Programmer("010", "kevin", "初级");
        p.doWork();
        System.out.println("------------");
        //经理子类 调用 重写方法
        Manager m = new Manager("006", "robin", 201.5);
        m.doWork();
    }
}
toString的重写:

        由于Object是顶级父类,因此可以说每个类都或多或少的直接或间继承了他,可以重写Object中的方法

        toString():返回对象所在的类以及他的地址值

                返回类型为String,返回的格式是类名@十六进制地址

        如果想要让他返回该对象的属性名及其值,可以对该方法进行重写

//toString原码
public String toString() {
    //返回 "类的全包名@该对象堆空间地址(十六进制形式)"
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

//重写toString方法
@Override
public String toString() {
    return "Teacher [name=" + name + ", balance=" + balance + "]";
}
(8)final关键字:
    定义:

         final是一个修饰符,表示最终的意思,可以用来修饰变量,方法,类。

用法:

1、final修饰类:

        用final修饰的类不能被继承,也就是说这个类是没有子类的。

        常见的被final修饰的类:String、Integer、Long、Double、Boolean、Character、Math等

public final class Action {
}
//编译报错
class Go extends Action {
}

2、final修饰方法:        

        final修饰的方法可以被子类继承,但不能被子类重写

        被final修饰的方法:Object里的wait()

public class Person {
    public final void print() {}
}
//编译报错
class Student extends Person {
    //从父类继承的final方法,不可以被重写
    public void print() {
    }
}

  3、final修饰变量:final修饰的变量成为了常量,只能被赋值一次,第二次会报编译错误

        (1)final修饰局部变量:

                注意局部变量赋初值之后,不能二次赋值,当他是形参的时候,传值后就已经赋初值了。

public void print(){
    final int a;
    a = 1;//第一次赋值
    
    a = 2;//编译报错,不能二次赋值·】
}


public void print2(final int a){
    a = 1;//编译报错,当执行该方法假设为person.print2(10)时,已经给a赋值为10了,方法中再赋值报错
}

        (2)final修饰非静态成员变量:

                初始化方法:

                ①显式初始化:定义的时候直接赋值

                ②构造代码初始化:先定义,然后到匿名代码块中赋值

                ③构造器初始化:先定义,然后再所有显式构造器中另外赋值,初始化

注意:每个构造器中赋的值可以不同,因为创建对象,只执行一次,不会有第二次复制,但必须在每个构造器中都初始化。

           set方法不可以用来给final修饰的变量赋值

class F {
    //第一种初始化方式:显式初始化
    //private final int num = 10;
    //第二种初始化方式:构造代码块初始化
    // private final int num;
    // {
        // num = 20;
    // }
    //第三种初始化方式:所有构造器中都对final成员进行初始化
    private final int num;
    public F() {
        //必须给num初始化
        this.num = 30;
    }
    public F(int num) {
        //必须给num初始化
        this.num = num;
    }
    @Override
    public String toString() {
        return "F [num=" + num + "]";
    }
}

        (3)final修饰静态成员变量             

                初始化方法:

                ①显式初始化:定义的时候直接赋值

                ②静态代码初始化:先定义,然后到静态代码块中赋值

class SF {
    //第一种初始化方式:显式初始化
    //private final static int num = 10;
    //第二种初始化方式
    private final static int num;
    static {
        num = 20;
    }
    //定义static方法,专门操作static数据成员
    public static int getNum() {
        return num;
    }
}

4、final修饰引用:

        final修饰引用类型变量时,变量的引用地址值不能改变(栈区内的地址不能改,堆区对应的空间中存放的数据可以改)

                

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值