继承
概述:
1.多个类中存在相同属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需再定义这些属性和行为,只有继承那个累即可。
2.多个类可以称为子类,单独这个类称为父类或者超类。
3.子类可以直接访问父类中的非私有的属性或者行为。
4.通过extends关键字让类与类之间产生继承关系。
5.继承的出现提高了代码的复用性。
6.让类与类之间产生了关系提供了多态的前提。
特点:
java只支持单继承,不支持多继承。单java支持多层继承。
多层继承:
class AAA{}
class BBB extends AAA{}
class CCC extends BBB{}
注意细节:
不要为了获取其他某个功能而去继承,类与类之间要有所属关系(is a):xx是xx的一种
继承下的类成员的特点
1.成员变量
如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this,访问父类中的同名变量用super
this代表本类对象的调用;super代表的是当前对象父类的引用。
2.成员函数
当子类出现和父类一模一样的函数时,当子类对象调用该函数时,会运行子类函数的内容——这是函数的另一特性:重写(覆盖)。
重写:子父类要一模一样; 重载:只看同名函数的参数列表。
3.构造函数
在对子类对象进行初始化时,父类的构造函数也会运行,因为子类的构造函数默认第一行有一条隐式的语句super();
super():会访问父类中空参数的构造方法,而且子类所有的构造方法默认第一行都是super()。
关键字:super
应用:
当子类出现同名成员时,可以用super进行区分。
当子类到调用父类构造方法时,可用super语句进行调用。
super的this的区别:
this:当前对象的引用,可引用成员变量。在自身构造方法内部引用其他构造方法,它代表自身类的对象引用成员方法。
super:当前对象里的父类的内存空间的标识。在子类的构造方法内部引用父类的构造方法,在子类中调用父类中的成员方法,在子类中调用父类中的成员变量。
函数的覆盖
子类中出现于父类一模一样的方法时,会出现覆盖操作,也称为重写或复写。在子类覆盖方法中继续使用被覆盖的方法可以通过super.函数名使用。父类中的私有方法不可以被覆盖。
应用:当子类需要父类的功能,而功能主体子类有自己的特有内容时,可以复写父类中的方法,这样,即沿袭父类的功能,又定义了子类特有内容。
注意:覆盖时,子类方法权限一定要大于等于父类方法权限,静态只能覆盖静态。
子类的实例化过程
1.子类的所有构造方法默认都会访问父类中空参数的构造函数,因为每一个子类的构造方法的第一行都有一条默认的语句super()。
2.子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的,当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。
继承的弊端:打破封装性。
关键字:final(最终)
特点:
1.final可以修饰类、方法、变量。
final修饰的类不可以继承。
final修饰的方法不可以覆盖。
final修饰的变量时一个常量,只能被赋值一次。
final修饰的变量只能在显示初始化或者构造函数初始化时赋值一次。
内部类只能访问final修饰的局部变量。
什么时候用?
2.当程序中一些不会变化的数据,也就是常见的常量值,就把它定义成final类型;当程序中某些功能不需要再升级也可以把它定义成final类型。
抽象类
概述:
抽象就是从多个事物中将共性的、本质的内容抽取出来。java中可以定义没有方法体的方法,该方法具体实现由子类完成。该方法就称为抽象方法,包含抽象方法的类就是抽象类。
由来:
多个对象都具备相同的功能,但是功能具体内容有所不同。那么在抽取过程中,只抽取了功能定义,并未抽取主体功能。那么只有功能声明没有功能主体的方法称为抽象方法
特点:
1.抽象方法一定在抽象类中。
2.抽象方法和抽象类都必须被abstract关键字修饰。
3.抽象类不可以new创建对象。
4.抽象类中的抽象方法要被使用,必须有子类复写所有的抽象方法,建立子类对象调用,如果子类只覆盖了部分的抽象方法,那么子类还是一个抽象类。
5.抽象类中可以有抽象方法也可以有非抽象方法。
6.抽象类比一般类多了个抽象函数,就是类中可以定义抽象方法。
特殊:抽象类中可以不定义抽象方法,这样仅仅是不让该类建立对象。
什么时候用?
当我们分析事物时,对对象进行描述时。其实就是不断把对象中的共享内容向上抽取,在抽取的过程中,发现对象具备相同的功能,但是功能的细节不同。这时在定义类时该功能是没有具体实例的,是由具体的对象来完成的。那么该功能就可以定义成抽象的。
总结:其实抽象类和一般类没什么不同,无非是多了一些没有方法体的函数。所以创建对象变得没有什么意义。
抽象类相关问题:
1.抽象类中是否有构造函数?——>有
2.抽象类关键字abstract不可以和哪些关键字共存?——>final、private、static。
3.抽象类中可不可以没有抽象方法?——>可以。
课后练习:
/*
雇员(Employee)示例:
需求:
公司中程序员(programmer)
有姓名(name),工号(id),薪水(pay),工作内容(work)。
项目经理(Manager)
除了有姓名(name),工号(id),薪水(pay),还有奖金(bonus),工作内容(work)。
对给出需求进行数据建模。
*/
class Doy08Test {
public static void main(String[] args) {
Programmer p = new Programmer("张超","4444",100);
Manager m = new Manager("周总","88888",100000);
p.Work();
p.Listing();
m.Work();
m.Listing(10000);
}
}
abstract class Employee{
public String name;
public String id;
public int pay;
public abstract void Work();
Employee(){}//此步很重要!!
Employee(String name,String id,int pay){
this.name = name;
this.id = id;
this.pay = pay;
}
}
class Programmer extends Employee{
Programmer(String name,String id,int pay) {
super(name,id,pay);
}
public void Work() {
System.out.println("工作编程敲代码");
}
public void Listing() {
System.out.println("姓名:"+name);
System.out.println("工号:"+id);
System.out.println("薪水:"+pay);
}
}
class Manager extends Employee{
int bonus;
public void Work() {
System.out.println("工作项目策划");
}
Manager(){}
Manager(String name,String id,int pay) {
super(name,id,pay);
}
public void Listing(int bonus) {
System.out.println("姓名:"+name);
System.out.println("工号:"+id);
System.out.println("薪水:"+pay);
System.out.println("奖金:"+bonus);
}
}