继承:权限修饰符
什么是权限修饰符?
- 就是是用来限制类中的成员(成员变量、成员方法、构造器、代码块..)能够被访问的范围。
权限修饰符有几种?各自的作用是什么?
修饰符 | 在本类中 | 在同一个包下的其他类里 | 任意包下的子类里 | 任意包下的任意类里 |
private | √ | |||
缺省(也就是不写修饰符) | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
能够被访问的范围由大到小分别为:public、protected、缺省、private。
在开发中,使用得最多的也就是public和private,其他两个权限修饰符只要求在看到源码时可以看得懂。
继承:单继承、Object类
单继承
- Java是单继承的,Java中的类不支持多继承,但是支持多层继承。
也就是说,一个类不能继承多个父类;但一个类继承的父类,该父类还可以作为一个子类再继承父类,称为多层继承。
例如:
//有ABCD三个类 class A{} class B extends A{} //B继承了A类,为单继承 class C extends B,A{} //C继承B类,再继承C类,会报错,为多继承 class D extends B{} //D继承了B类,而B类继承了A类,为多层继承
Object类
object类是java所有类的祖宗类。我们写的任何一个类,其实都是object的子类或子孙类。
也就是说,我们创建一个类的时候,如果没有继承类,那么就会默认继承Object类,为Object的子类;而如果已经继承了类,那么也是间接继承了Object类,也就是Object的子孙类,都是可以调用Object类里面的方法的。
1. class A /* extends Object */ ; 2. class B extends A; //多层继承了Object类
继承:方法重写
什么是方法重写?
- 当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称,参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。
- 注意:重写后,方法的访问,Java会遵循就近原则。
方法重写的注意事项
- 重写小技巧:使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
- 子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限(public>protected>缺省)。
- 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
- 私有方法、静态方法不能被重写,如果重写会报错的。
方法重写在开发中的常见应用场景
- 子类重写Object类的toString()方法,以便返回对象的内容
不重写toString方法时,直接输出对象只会输出对象的地址:
重写之后,就可以输出对象的内容了
也可以使用IDEA的快捷操作重写toString方法:
1.方法重写是什么?
- 子类写了一个方法名称,形参列表与父类某个方法一样的方法去覆盖父类的该方法。
2.重写方法有哪些注意事项?
- 建议加上:@Override注解,可以校验重写是否正确,同时可读性好。
- 子类重写父类方法时,访问权限必须大于或者等于父类被重写的方法的权限。
- 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
- 私有方法、静态方法不能被重写。
3.方法重写有啥应用场景?
- 当子类觉得父类的方法不好用,或者不满足自己的需求时,就可以用方法重写。
继承:子类访问成员的特点
- 子类方法中访问其他成员(成员变量、成员方法),是依照就近原则的。
也就是:先子类局部范围找,然后子类成员范围找;然后父类成员范围找,如果父类范围还没有找到则报错。
如果子父类中,出现了重名的成员,会优先使用子类的,如果此时一定要在子类中使用父类的怎么办?
- 可以通过super关键字,指定访问父类的成员:super.父类成员变量/父类成员方法
public class F{ String name = "父类名称"; } public class Z extends F{ String name = "子类名称"; public void showName(){ String name = "局部名称"; System.out.println(name); //局部名称 System.out.println(this.name); //子类名称 System.out.println(super.name); //父类名称 } }
继承:子类构造器的特点
- 子类的全部构造器,都会先调用父类的构造器,再执行自己。
这是因为子类的有参或无参构造器,都会默认调用一个super方法,先执行父类的构造器。
如果父类没有无参构造器(也就是写了有参构造器,不默认生成无参构造器),那么此时子类调用构造器就会报错,因为找不到父类的无参构造器;解决方法是给子类构造器的super方法写上参数,让其调用父类的有参构造器。
应用场景
- 为对象中包含父类这部分的成员变量进行赋值。
在继承的情况下,由于处理对象数据的构造器拆到了多个类里去了,所以对象要通过调用多个构造器,才能把对象的数据处理得完整。
子类构造器可以通过调用父类构造器,把对象中包含父类这部分的数据先初始化赋值再回来把对象里包含子类这部分的数据也进行初始化赋值。
补充知识:this调用兄弟构造器
- 任意类的构造器中,是可以通过this(..)去调用该类的其他构造器的。
类似于:
public Student(String name,int age){ this(name,age,"**da大学"); } public Student(String name,int age,String schoolName){ super(); //默认存在 this.name = name; this.age = age; this.schoolName = schoolName; }
注意:this(..)、super(..)都只能放在构造器的第一行,因此,有了this(...)就不能写super(...)了,反之亦然。
1.子类构造器有啥特点?
- 子类中的全部构造器,都必须先调用父类的构造器,再执行自己
2、super(..)调用父类有参数构造器的常见应用场景是什么?
- 为对象中包含父类这部分的成员变量进行赋值。
3、this(...)的作用是什么?
- 在构造器中调用本类的其他构造器。
4、this(...和super(...)的使用需要注意什么?
- 都必须放在构造器的第一行。
END