一、方法重写的概述:
子类中出现了和父类中方法声明一模一样的方法声明,也被称为方法覆盖、方法复写。
使用特点:
1.如果方法名不同,就调用对应的方法。
2.如果方法名相同,最终使用的是子类自己的。
二、方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己的特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
注意事项:
1.父类中私有方法不能被重写;
2.子类重写父类方法时,访问权限不能更低;
3.父类静态方法,子类也必须通过静态方法进行重写;
//方法重写
package test4;
class Phone{
/*private void call(String name){
System.out.println("给"+name+"打电话");
}*/
public void call(String name){
System.out.println("给"+name+"打电话");
}
}
class NewPhone extends Phone{
/*private void call(String name){
super.call(name);
System.out.println("可以听天气预报了");
}*/
public void call(String name){
super.call(name);
System.out.println("可以听天气预报了");
}
}
public class Example3_1 {
public static void main(String[] args) {
NewPhone sc = new NewPhone();
sc.call("林青霞");
}
}
三、super与this关键字的使用
概述:super的用法和this很像,this代表本类对应的引用,super代表父类存储空间的标识(可以理解为父类引用)。
那么怎么使用呢?
1.调用成员变量:
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
2.调用构造方法
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
3.调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
继承中所有的构造方法默认都会访问父类中空参数的构造方法,为什么呢?
因为子类会继承父类中的数据,可能还会使用父类的数据,所以子类初始化之前,一定要完成父类数据的初始化;
子类每一个构造方法的第一条语句默认都是super(),如果父类没有无参构造方法,那么,子类构造方法就会报错,如何解决呢?
1.在父类中加一个无参构造方法;
2.子类通过super去显示调用父类的其他构造方法;
3.子类通过this去调用本类的其他构造方法(本类其他构造方法必须首先访问了父类构造方法)
注意:super(...)或this(..)必须出现在第一条语句,否则就会有父类数据的多次初始化。
小总结:
1.成员变量的问题:
int x = 10;//成员变量为基本类型;
Student s = new Student();//成员变量是引用类型
2.一个类的初始化过程:
默认初始化
显示初始化
构造方法初始化
3.子父类的初始化(分层初始化):
先进行父类初始化,然后进行子类初始化;
4.继承中成员方法的关系:
(1):首先在子类找
(2):然后在父类中找
(3):如果还没有就报错(不考虑父亲的父亲)
//super与this的使用案例
class Father2{
//public Father2(){
// System.out.println("father的无参构造方法");
//}
public Father2(int m){
System.out.println("F的有参构造方法");
}
}
class Son2 extends Father2{
public Son2(){
super(10);
System.out.println("son的无参构造方法");
}
public Son2(int m){
//super(10);//显示调用父类其他构造方法
this();//访问本类的其他构造方法
System.out.println("son的有参构造方法");
}
}
public class Example2_6 {
public static void main(String[] args){
//创建对象
Son2 sc = new Son2();//结果为F的有参构造方法,son的无参构造方法
Son2 sc1 = new Son2(10);//结果为F的有参构造方法,son的无参构造方法,son的有参构造方法
}
}
四、final关键字的使用
final可以用来修饰类、方法、变量。
特点:
1.final修饰类,该类不能被继承;
2.final修饰方法,该方法不能被重写;
3.final可以修饰变量,该变量不能被重新赋值;(变量为常量)
常量分为:
1.字面值常量:“hello”,10,true;
2.自定义常量:final int x = 10;
面试题:final修饰局部变量的问题?
1.基本类型:基本类型的值不发生改变;
2.引用类型:引用类型的地址值不能改变,但是,该对象的堆内存的值可以改变;
//final关键字的使用
package test4;
//修饰类时
/*final class Fu{
}*/
class Father{
public int num1 = 10;
public final int num2 = 20;
//修饰方法时
/*public final void show(){
}*/
public void show(){
}
}
class Son extends Father{
public void show(){
num1 = 30;
//num2 = 100;//被final修饰不能被更改
System.out.println(num1);
System.out.println(num2);
}
}
public class Example3_4 {
public static void main(String[] args) {
Son sc = new Son();
sc.show();
}
}
最后,使用继承后的学生和老师案例,代码如下:
//使用继承后的学生和老师案例
package test4;
class People{
private String name; //姓名
private int age; //年龄
public People(){
}
public People (String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
class Student extends People{
public Student(){
}
public Student(String name,int age){
super(name,age);
}
}
class Teacher extends People{
public Teacher(){
}
public Teacher(String name,int age){
super(name,age);
}
}
public class Example3_2 {
public static void main(String[] args) {
//方式一
Student sc1 = new Student();
sc1.setAge(27);
sc1.setName("林青霞");
System.out.println(sc1.getName()+"----"+sc1.getAge());
//方式二
Teacher sc2 = new Teacher("林青霞",27);
//Teacher sc2 = new Teacher();
//sc2.setAge(60);
//sc2.setName("linqingxia");
System.out.println(sc2.getName()+"-----"+sc2.getAge());
}
}