目录
1. 继承
1.1 继承概述
1.2 继承特点
1.3练习
1.4继承父类的内容
构造方法是否被子类继承
成员变量是否被子类继承
成员方法是否被子类继承
1.5总结
继承中:成员变量的访问特点
继承中:成员方法的访问特点
方法重写概述
方法重写的本质
继承中:构造方法的特点
this,super使用总结
1. 继承
1.1 继承概述
继承是面向对象的三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
继承是指在原有类的基础上,进行功能扩展,创建新的类型。
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
JAVA中类只有单继承,没有多继承!
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
子类和父类之间,从意义上讲应该具有"is a"的关系。
extends的意思是“扩展”,子类是父类的扩展。
继承的格式:
- 格式: public class 子类名 extends 父类名{}
- 例如: public class Zi extends Fu {}
- Fu:是父类,也被称为基类、超类
- Zi: 是子类,也被称为派生类
继承中子类的特点:
子类可以有父类的内容,子类还可以有自己特有的内容。
1.2 继承特点
Object类是所有子类的父类 如果你没有写父类 默认父类就是Object类
1.3练习
如果父类加了private私有关键字 ,子类就不能使用父类的特性了
测试类
package comitheima.a01oopextendsdemo01;public class Test {public static void main(String[] args) {//1.创建布偶猫对象Ragdoll r1 = new Ragdoll();r1.eat();r1.drink();r1.catchMouse();System.out.println("----------------");//2.创建哈士奇对象Husky h=new Husky();h.eat();h.drink();h.DownHome();}}
package comitheima.a01oopextendsdemo01;public class animal {public void eat(){System.out.println("吃饭");}public void drink (){System.out.println("喝水");}
}
package comitheima.a01oopextendsdemo01;public class cat extends animal {public void catchMouse(){System.out.println("猫在抓老鼠");}
}
package comitheima.a01oopextendsdemo01;public class dog extends animal {public void watchhose(){System.out.println("狗在看家");}
}
package comitheima.a01oopextendsdemo01;public class Husky extends dog {public void DownHome(){System.out.println("哈士奇拆家");}}
package comitheima.a01oopextendsdemo01;public class LiHua extends cat {
}
package comitheima.a01oopextendsdemo01;public class Ragdoll extends cat {}
package comitheima.a01oopextendsdemo01;public class Teddy extends dog {public void touch(){System.out.println("泰迪蹭一蹭");}
}
1.4继承父类的内容
构造方法是否被子类继承
构造方法的类名和子类的类名不一样,违背了构造方法的特征,所以父类的构造方法不能被子类继承
package comitheima.a01oopextendsdemo02;public class Test {public static void main(String[] args) {Zi zi = new Zi();//Zi zi1 = new Zi("zhasa",18);}
}class Fu{String name;int age;public Fu(String name, int age) {this.name = name;this.age = age;}public Fu(){}
}
class Zi extends Fu{//如果一个类没有构造方法,虚拟机会自动给你添加一个默认的空参的构造方法
}
说明了子类没有继承父类的构造方法,空参构造也是虚拟机给的
成员变量是否被子类继承
public修饰的成员变量
对象先找子类再找父类
private修饰的成员变量
private修饰的变量 子类调用不了变量只能继承不能直接使用
成员方法是否被子类继承
只有非static修饰 非private修饰非final修饰的方法是虚方法
虚方法就可以继承给子类,子类就会加载方法,每次子类调用方法的时候就可以从自己的虚方法里面去调用
1.5总结
1.构造方法的类名和子类的类名不一样,违背了构造方法的特征,所以父类的构造方法不能被子类继承,不管是public修饰还是private修饰都不能被子类继承
2.成员变量不管是private修饰还是public修饰都能继承 ,但是private修饰的成员变量只能继承不能直接调用
3. 只有public修饰的成员方法才能继承,private修饰的成员方法不能继承
4.只有非static修饰 非private修饰非final修饰的方法是虚方法
虚方法就可以继承给子类,子类就会加载方法,每次子类调用方法的时候就可以从自己的虚方法里面去调用
继承中:成员变量的访问特点
遵循就近原则
在子类方法中访问一个变量
最先在子类局部范围找,如果没有就在子类成员范围找,最后在父类成员范围找,如果都没有就报错(不考虑父亲的父亲...)。
name先在局部位置找,然后再到本类的成员位置找,然后在到父类找,一级一级往上找
this访问的是本类的成员变量 ,super是访问父类的成员变量
例如:创建一个父类Fu
public class Fu {public int age = 10; }
创建一个子类Z
public class Zi extends Fu {public int heigth = 180;public int age = 20;// 若果没有这句,和下面那句,输入的是10public void show() {int age = 30;// 若果没有这句,输入的是20System.out.println(age);System.out.println(heigth);} }
创建一个测试类Test
public class Test {public static void main(String[] args) {// 创建对象调用方法Zi z = new Zi();z.show();} }
结果:
继承中:成员方法的访问特点
通过子类对象访问一个方法:
先子类成员范围找,如果找不到就在父类成员范围找,如果都没有就报错(不考虑父亲的父亲...)
方法重写概述
方法重写概述:子类中出现了和父类中一模一样的方法声明
方法重写的应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
@Override
是一个注解可以帮助我们检查重写方法的方法声明的正确性
方法重写的本质
只有被添加到虚方法中的方法才能被重写
package comitheima.a01oopextendsdemo04;import java.util.SimpleTimeZone;public class Dog {public void eat() {System.out.println("狗在吃狗粮");}public void drink(){System.out.println("狗在喝水");}public void lookhome(){System.out.println("狗在看家");}
}
package comitheima.a01oopextendsdemo04;public class Husky extends Dog {public void downhome(){System.out.println("哈士奇在拆家");}
}
package comitheima.a01oopextendsdemo04;public class Chinesedog extends Dog {public void eat(){//父类的方法不能满足我们的需求,所以进行了重写,且父类的方法我根本用不到System.out.println("中化田园犬在吃剩饭");}
}
package comitheima.a01oopextendsdemo04;public class sharper extends Dog {//因为沙皮狗吃的是狗粮和骨头//父类的方法不能满足我们的需求,所以进行了重写//方法重写@Overridepublic void eat(){super.eat();System.out.println("沙皮狗在吃骨头");}
}
package comitheima.a01oopextendsdemo04;public class Test {public static void main(String[] args) {Husky h= new Husky();h.eat();h.drink();h.lookhome();h.downhome();System.out.println("----------");sharper sh=new sharper();sh.eat();sh.drink();sh.lookhome();System.out.println("----------");Chinesedog Ch=new Chinesedog();Ch.eat();Ch.drink();Ch.lookhome();}
继承中:构造方法的特点
子类中所有的构造方法默认都会访问父类中无参的构造方法。
- 因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
- 每一个子类构造方法的第一条语句默认都是: super()
例如:创建一个父类Fu
public class Fu {public Fu() {System.out.println("Fu中无参构造方法被调用");}public Fu(int age) {System.out.println("Fu中带参构造方法被调用");}
}
创建一个子类Zi
public class Zi extends Fu {public Zi() {// super();System.out.println("Zi中无参构造方法被调用");}public Zi(int age) {// super();System.out.println("Zi中带参构造方法被调用");}
}
测试:Test
public class Test {public static void main(String[] args) {Zi z = new Zi();System.out.println("-------------------");Zi zi = new Zi(18);}
}
子类的初始化之前,要调用父类的构造方法先完成父类的数据初始化
如果想要调用父类的有参构造 ,必须手动加上super.
我还想强调的是父类的构造方法,子类是不能继承,但是子类可以去调用父类的方法,继承不了不代表调用不了,不管是private修饰还是public修饰的构造方法,子类都继承不了父类的构造方法
如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?
- 通过使用super关键字去显示的调用父类的带参构造方法
- 在父类中自己提供一个无参构造方法
- 推荐: 自己给出无参构造方法
例如:创建一个父类Fu
public class Fu {// public Fu() {// System.out.println("Fu中无参构造方法被调用");// }public Fu(int age) {System.out.println("Fu中带参构造方法被调用");} }
创建一个子类Zi
public class Zi extends Fu {public Zi() {super(18);System.out.println("Zi中无参构造方法被调用");}public Zi(int age) {super(18);System.out.println("Zi中带参构造方法被调用");}
}
测试:Test
public class Test {public static void main(String[] args) {Zi z = new Zi();System.out.println("-------------------");Zi zi = new Zi(18);}
}
super访问父类的构造方法
package comitheima.a05oopextendsdemo05;public class Student extends Person{public Student(){//子类构造方法中隐藏的super()去访问父类的无参构造super();System.out.println("子类的无参构造");}public Student(String name,int age){//子类构造方法中手动去在super方法中传参数 就可以去调用带参构造super(name,age);System.out.println("子类的无参构造");}
}
package comitheima.a05oopextendsdemo05;public class Test {public static void main(String[] args) {Student s1 = new Student("zhangsa",18);System.out.println(s1.name+" "+s1.age);}
}
package comitheima.a05oopextendsdemo05;public class Person {String name;int age;public Person() {System.out.println("父类的无参构造");}public Person(String name, int age) {this.name = name;this.age = age;}
}
this,super使用总结
例如:定义一个父类Fu
public class Fu {public int age = 10;}
定义一个子类Zi
public class Zi extends Fu {public int age = 20;public void show() {int age = 30;System.out.println(age); // 30// 访问本类中的成员变量ageSystem.out.println(this.age);// 访问Fu类中的成员变量ageSystem.out.println(super.age);} }
测试:Test
public class Test {public static void main(String[] args) {Zi z = new Zi();z.show();} }
this访问本类的构造方法
测试类
package comitheima.a06oopextendsdemo06;import com.sun.tools.javac.Main;public class Test {public static void main(String[] args) {Manager m=new Manager("001","zhangsan",6666,1000.0);System.out.println(m.getId()+" "+m.getName()+" "+m.getSalary()+" "+m.getBonus());m.word();m.eat();System.out.println("--------------");Cook c=new Cook("002","lisi",1111);System.out.println( c.getId()+" "+c.getName()+" "+c.getSalary());c.word();c.eat();}
}
父类
public class Employee {private String id;private String name;private int salary;public Employee() {}public Employee(String id, String name, int salary) {this.id = id;this.name = name;this.salary = salary;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}public void word(){System.out.println("员工在工作");}public void eat(){System.out.println("在吃米饭");}
}
子类经理类
public class Manager extends Employee {private double bonus;public Manager() {}//带全部的构造方法//父类+子类的构造方法public Manager(String id, String name, int salary, double bonus) {super(id, name, salary);//调用父类的有参构造,把id,name,salary,bonus的值给父类this.bonus = bonus;//子类的特有的奖金在本类赋值}public double getBonus() {return bonus;}public void setBonus(double bonus) {this.bonus = bonus;}@Overridepublic void word() {System.out.println("经理在管理其他人");}}
子类厨师类
package comitheima.a06oopextendsdemo06;public class Cook extends Employee {public Cook() {}public Cook(String id, String name, int salary) {super(id, name, salary);}@Overridepublic void word() {System.out.println("厨师在炒菜");}
}