继承
继承解决的问题是共性抽取,把共性的内容抽取到父类中,子类可以直接使用。从而提高了代码的复用性。
继承的格式
public class 子类 extends 父类{
//成员变量
//成员方法
//构造方法
}
继承的好处和弊端
好处:提高了代码的复用性
弊端:增强的代码的耦合性
什么时候使用继承?
答:有共性才使用继承,没有共性就不使用继承。
继承的特点
1.Java只支持单继承
一个儿子只能有一个爸爸
2.Java可以多层继承
儿子可以有爸爸,爸爸也可以有爸爸
注意:所有的都直接或者间接的继承Object类
继承中成员的访问特点
- 成员变量的访问特点
遵循就近原则
1.先在方法内部找,再到本类的成员位置找,再到父类的成员位置找。如果都找不到就报错
2.当子类和父类出现同名的变量,可以使用this和super进行区分
this.变量名: 本类的成员变量
super.变量名: 父类的成员变量
public class Fu{
int num=10;
}
public class Zi extends Fu{
int num=20;
public void show(){
int num=30;
System.out.println(num); //30
System.out.println(this.num); //20,本类的成员变量
System.out.println(super.num); //10,父类的成员变量
}
}
- 成员方法的访问特点
遵循就近原则
1.先本类找方法,再到父类找方法(也可以到父类的父类中找)。如果都找不到就报错
2.当子类和父类出现同名的方法,可以使用this和super进行区分
this.方法名(): 本类的方法
super.方法名(): 父类的方法
public class Fu{
public void show(){
System.out.println("fu...show");
}
}
public class Zi{
public void show(){
System.out.println("zi...show");
}
public void method(){
show(); //调用本类的show()方法
this.show(); //调用本类的show方法
super.show(); //调用父类的show方法
}
}
构造方法的访问特点
1.子类中每一个构造方法,都会默认的调用父类的空参数构造方法
原因:在构造方法的第一行有一句隐含的 super()
2.如果父类没有空参数构造方法,子类构造方法可以使用 super(参数) 调用父类有参数构造方法
3.this()或者super()只能写在构造方法的第一条语句
小建议:建议在写构造方法时,都把空参数构造方法加上。
this和super小结
this: 本类对象的引用
this.成员变量 //本类的成员变量
this.成员方法 //本类的成员方法
this() //本类的空参数构造方法
this(参数) //本类的有参数构造方法
super: 父类对象的引用
super.成员变量 //父类的成员变量
super.成员方法 //父类的成员方法
super() //父类的空参数构造方法
super(参数) //父类的有参数构造方法
方法重写
1.方法重写概述:
在继承系统中,子类和父类出现了一模一样的方法声明(方法名、参数列表、返回值类型都一样)
2.方法重写的意义:
既保留了父类方法,子类也有自己的实现
3.方法重写的注意事项:
1.父类的私有方法和静态方法不能复写
2.子类复写父类方法,权限必须大于或者等于父类
public > protected > 默认的(不写) > private
public class Fu{
public void show(){
System.out.pritnln("fu...show...");
}
}
public class Zi extends Fu{
//检查方法是否符合复写的规则
@Override
public void show(){
System.out.pritnln("zi...show...");
}
}
抽象
抽象类和抽象方法
//抽象类
public abstract class 类名{
//抽象方法
public abstract void 方法名();
}
- 抽象的注意事项
1.abstract可以修饰类也可以修饰方法
2.有抽象方法的类必须是抽象类,抽象类中可以有非抽象方法
3.子类继承抽象类,必须重写所有的抽象方法
4.子类如果也是抽象类,可以不复写抽象方法
5.抽象类不能创建对象
6.抽象方法没有方法体
public abstract void A{ //定义一个抽象类
public abstract void show(); //定义一个抽象方法,没有方法体
public void eat(){
sout{...}//抽象类中可以定义非抽象方法
}
}
模板设计模式
把共性内容写成一个父类,把可以确定的行为形成具体方法,把不能确定的行为写成抽象方法,抽象方法具体的实现交给子类去完成。
//定义一个模板类,body是抽象的
public abstract class Tempalate{
public void write(){
//开头
System.out.println("作文的开头");
//正文
body();
//结尾
System.out.println("作文的结尾");
}
public abstract void body();
}
public class Tom extends Tempalate{
//复写正文的方法
public void body(){
System.out.println("作为的正文");
}
}
格式:
父类:
public abstract class Template{ //抽象类中可以有非抽象的方法
public void write(String str){ //参数传递
sout("<<我的爸爸>>")
body(str);
sout("这就是我的爸爸")
}
public abstract void body(String str); //注意参数的传递
}
子类:
public class Student extends Template{
public void body(String str){
sout(str);
}
}
测试类:
public class StudentTest{ //注意:测试类中缺少psvm,将无法运行!主方法是程序的入口! Student stu = new Student(); //不要犯低级错误
stu.write("我的爸爸很有钱");
}
final关键字
final是最终的意思,可以修饰类、方法和变量
1.final修饰类: 不能有子类
2.final修饰方法: 不能被重写
3.final修饰变量:
1)final修饰基本类型: 变量值不能发生改变(只能被赋值一次)
2)final修饰引用类型: 变量的地址值不能发生改变(只能记录一个地址)
4.书写格式: final int NUM = 10; //单个字母变量名大写
final int MAX_NUM = 10; //多个字母组成的变量名大写,中间用_连接
代码块
代码块就是使用大括号括起来的内容,根据在类中的位置不同分为三种
1.局部代码块:在方法中的{...}
作用:限定变量的作用域
2.构造代码块:在类的成员位置的{...}
作用:提取构造方法中的共性代码,提高代码的复用性
每次创建对象,构造代码块都会执行,而且是执行在构造方法之前。
3.静态代码块:在类的成员位置,static{...}
作用:给类做一些初始化的操作
静态代码块只执行一次