继承
一.概述
1.定义了多个类,多个类中有很多重复性代码,就定义一个父类,将重复性代码抽取到父类中,然后让这些类继承父类,这些重复性代码只用在父类中写.
2.子类可以继承父类中所有成员(私有和非私有),但只可以使用父类非私有成员,不能使用私有成员 ,构造方法不能被继承
3.继承是一种代码设计思想,可遵守可不遵守
4.继承不要从 有没有 来看,要从能不能 使用 来看
二.使用
子类 extends 父类
三.继承中,成员变量和成员方法的访问特点
成员变量
- 子类和父类的成员变量不重名
public class Fu {
int numFu = 1000;
}
public class Zi extends Fu{
int numZi = 100;
}
public class Test01 {
public static void main(String[] args) {
Fu fu = new Fu();
System.out.println(fu.numFu);//调用的父类中的成员变量
//System.out.println(fu.numZi);//不能调用子类特有的成员
Zi zi = new Zi();
System.out.println(zi.numZi);//子类的numZi
System.out.println(zi.numFu);//从父类中继承过来的
}
}
- 子类和父类中的成员变量重名
public class Fu {
int numFu = 1000;
int num = 10000;
}
public class Zi extends Fu{
int numZi = 100;
int num = 1;
}
public class Test01 {
public static void main(String[] args) {
Fu fu = new Fu();
System.out.println(fu.numFu);//调用的父类中的成员变量
//System.out.println(fu.numZi);//不能调用子类特有的成员
System.out.println(fu.num);//父类中的num
Zi zi = new Zi();
System.out.println(zi.numZi);//子类的numZi
System.out.println(zi.numFu);//从父类中继承过来的
System.out.println(zi.num);//子类中的num
}
}
看等号左边是谁,先调用谁中的成员变量,子类没有找父类
成员方法
- 子类和父类中的成员方法不重名
public class Fu {
public void methodFu(){
System.out.println("我是父类中的methodFu方法");
}
}
public class Zi extends Fu{
public void methodZi(){
System.out.println("我是子类中的methodZi方法");
}
}
public class Test01 {
public static void main(String[] args) {
Fu fu = new Fu();
fu.methodFu();
//fu.methodZi();//不能调用子类特有的
System.out.println("========");
Zi zi = new Zi();
zi.methodZi();
zi.methodFu();
}
}
- 子类和父类中的成员方法重名
public class Fu {
public void methodFu(){
System.out.println("我是父类中的methodFu方法");
}
public void method(){
System.out.println("我是父类中的method方法");
}
}
public class Zi extends Fu{
public void methodZi(){
System.out.println("我是子类中的methodZi方法");
}
public void method(){
System.out.println("我是子类中的method方法");
}
}
public class Test01 {
public static void main(String[] args) {
Fu fu = new Fu();
fu.methodFu();
//fu.methodZi();//不能调用子类特有的
fu.method();//父类中的method
System.out.println("========");
Zi zi = new Zi();
zi.methodZi();
zi.methodFu();
zi.method();//子类中的method
}
}
看new的是谁,先调用谁中的成员方法,子类没有找父类
四.方法的重写
1.子类中有一个和父类方法名,参数列表一模一样的方法
2.检测@Overrride
3.如果new的是子类对象,调用子类重写的方法,子类没有找父类
4.注意事项
- 子类方法重写父类方法,必须要保证权限大于等于父类权限。(权限指的是权限修饰符)
public->protected->默认->private - 子类方法重写父类方法,方法名和参数列表都要一模一样。
- 私有方法不能被重写,构造方法不能被重写
- 子类重写父类方法之后,返回值类型应该是父类方法返回值类型的子类类型
5.方法的升级改造时用到
super this
1.继承中构造方法的特点
1.注意:
初始化子类对象之前先调用父类无参构造
2.为啥:
因为每一个构造方法第一行都会默认有一个super(),是jvm给的,不写也有
3.super():代表的是父类无参构造
如果要是手写出来,super()必须写在构造中,而且必须要写在构造第一行
2.super和this的具体使用
super的使用
1.概述:代表的是父类引用
2.作用:调用父类的成员
3.使用:
-
调用父类的构造方法:在子类构造方法中写
super()
super(实参)
-
调用父类的成员变量
super.成员变量名
-
调用父类中的成员方法
super.成员方法名
4.注意事项:
构造方法中第一行默认会有一个super(),而且手写super()或者super(实参)必须在构造第一行
this的具体使用
1.this代表当前对象
2.作用:区分重名的成员变量和局部变量
3.使用:
-
调用当前对象的构造:在构造中
this():调用无参构造
this(实参):调用有参构造
-
调用当前对象的成员变量
this.成员变量名
-
调用当前对象的成员方法
this.成员方法名(参数)
4.注意事项
this()或者this(实参) 如果要是在构造中写出来,那么必须要在构造第一行 所以this和super不能同时出现在构造里
public class Zi {
int num = 100;
public Zi(){
this(1);
System.out.println("我是无参构造");
}
public Zi(int i){
//this();
System.out.println("我是有参构造");
}
public void method(){
int num = 1000;
System.out.println(num);//局部的num
System.out.println(this.num);//成员的num
//this.method01();
method01();
}
public void method01(){
System.out.println("method01");
}
}
3.继承的特点
1.构造方法不能被继承,私有方法不能被重写,静态方法不能被重写
2.特点:
a.继承只支持单继承,不能多继承-> 一脉单传
public class A extends B,C -> 不行
b.继承支持多层继承:
public class A extends B
public class B extends C
c.一个父类可以有多个子类
public class A extends B
public class C extends B
4.为父类中private的成员变量赋值
利用父类公共接口set和get方法对成员变量赋值及打印
public class Employee {
private String name;
private int age;
public Employee() {
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void work(){
System.out.println("人要工作");
}
}
public class Manager extends Employee {
}
public class Test01 {
public static void main(String[] args) {
Manager manager = new Manager();
//manager.name = "";
manager.setName("张三");
manager.setAge(36);
System.out.println(manager.getName()+"..."+manager.getAge());
}
}