目录
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;// 若果没有这句,和下面那句,输入的是10 public void show() { int age = 30;// 若果没有这句,输入的是20 System.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 {
//因为沙皮狗吃的是狗粮和骨头
//父类的方法不能满足我们的需求,所以进行了重写
//方法重写
@Override
public 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 // 访问本类中的成员变量age System.out.println(this.age); // 访问Fu类中的成员变量age System.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;
}
@Override
public 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);
}
@Override
public void word() {
System.out.println("厨师在炒菜");
}
}