继承(extends):
概述:
我们在定义一个类的时候,不需要从头开始。可以在某些类的基础上,扩充自己的功能即可。让我们的类和那个已经存在的类产生一个关系,我就能够具备别人的成员。这个关系:继承。
继承的好处:
A:提高代码的复用性。
B:让类与类之间产生了一个关系,是多态的前提。
继承的弊端:
破坏了耦合性。类之间的关系过强,会导致一个类的改动直接影响其他的类。
继承的特点:
1、子类可以直接访问父类中的非私有的属性和行为
子类不可以具备父类中私有的内容。
代码解析:
class Animal {
Stringname = "史努比";
privateint age = 3;
//吃的方法
publicvoid eat(){
System.out.println("eat");
}
}
//子类继承父类
class Dog extends Animal { }
class ExtendsDemo {
publicstatic void main(String[] args) {
//创建对象
Dogd = new Dog();
System.out.println(d.name);
//错误: age不可以在Animal中访问private
//System.out.println(d.age);
}
}
2、Java只支持单继承,不支持多继承
代码解析:
class Fu {
public void show(){
System.out.println("fushow");
}
}
class Fu2 {
public void play(){
System.out.println("Fu2play");
}
}
//报错
//class Zi extends Fu,Fu2 {
}
class Zi extends Fu {
}
class ExtendsDemo2{
public static voidmain(String[] args) {
Zi z = new Zi();
z.show();
}
}
3、Java支持多层继承(继承体系)
定义继承需要注意:
1:不要仅为了获取其他类中某个功能而去继承
2:类与类之间要有所属( " is a " )关系,xx1是xx2的一种。
简单描述:看看是不是爹和儿子的关系,是的话,可以使用继承
任何一个类它们都是有父亲的,这个最终的父亲就是object它是java中的一个类 object 是所有类的父亲
class Yy extends Object {}
代码解析:
class Yy {
String sex = "男";
}
class Fu extends Yy {
public void show(){
System.out.println("哈罗");
}
}
class Zi extends Fu {
}
class ExtendsDemo3 {
public static voidmain(String[] args) {
Zi z = new Zi();
z.show();
System.out.println(z.sex);
}
}
继承中成员变量的调用方法:
1:this代表的是本类对象的引用
2:super代表父类的内存空间的标识。
3:当子父类出现同名成员时,可以用super进行区分
4:子类要调用父类构造函数时,可以使用super语句。
调用本类成员变量:
this.成员变量
调用父类成员变量:
super.成员变量
如果方法中局部变量与类中成员变量名字重复,使用this区别
如果类中成员变量与父类中成员变量名字重复,使用super区别
变量的使用原则:就近原则
代码解析:
class Fu {
int num = 10;
}
class Zi extends Fu {
int num = 20;
public void show(){
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
class ExtendsDemo4 {
public static voidmain(String[] args) {
Zi z = new Zi();
z.show();
}
}
继承中成员方法的调用方法:
1: 调用本类中的成员方法
this.方法名
2:调用父类中的成员方法
super.方法名
函数覆盖(Override):
1:子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。 方法的重写
2:父类中的私有方法不能被覆盖。
3:在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。
覆盖注意事项:
1:覆盖时,子类方法权限一定要大于等于父类方法权限
2:静态只能覆盖静态。
覆盖的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,
这样,即沿袭了父类的功能,又定义了子类特有的内容。
代码解析:
class Fu {
public void method(){
System.out.println("method");
}
public void show(){
System.out.println("fushow");
}
public static void show2(){
System.out.println("fustatic show");
}
}
class Zi extends Fu {
public void function() {
System.out.println("function");
}
//错误: show()不可以在Zi中访问private
//private void show(){}
public void show(){
System.out.println("zishow");
super.show();
}
//错误: Zi中的show2()无法覆盖Fu中的show2() 静态只能覆盖静态
//public void show2(){}
public static void show2(){
System.out.println("zistatic show");
}
}
class ExtendsDemo5 {
public static voidmain(String[] args) {
//Fu f = new Fu();
//f.method();
//f.function();
Zi z = new Zi();
z.function();
z.method();
z.show();
z.show2();
}
}
继承中的构造方法的使用方式::
1:子类中所有的构造函数默认都会访问父类中空参数的构造函数 super()
2:每一个构造函数的第一行都有一条默认的语句super();
3:子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
4:当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。
本类构造方法的调用:
this(参数)
父类构造方法的调用:
super(参数)
final关键字:
final:最终的
final可以修饰类,方法,变量。
final修饰的方法不可以被覆盖。
final修饰的变量是一个常量。只能被赋值一次。
final修饰的类不可以被继承
抽象类:
如果多个类中有相同的方法声明,而方法体不一样,我们就可以只抽取方法声明,定义到一个类中。
而一个方法如果没有方法体,也就是说该方法不是具体的,只能是一个抽象的,又因为一个类中有抽象
方法,该类必须定义为抽象类。
抽象类的特点:
A:抽象类和抽象方法都必须用abstract修饰。
B:抽象类被子类继承的时候:
要么子类全部重写抽象方法。
要么子类是一个抽象类。
C:抽象类不能被实例化。
为什么会有构造方法呢?
用于子类访问父类数据的初始化。
D:抽象类中的非抽象方法,可以被子类继承并使用。
抽象类中的抽象方法,是要求子类必须做某些事情。
抽象类的成员:
1:构造方法:
有,当子类创建对象的时候,会调用默认super(),会调用父类中构造方法,
作用:可以为父类中成员进行初始值的操作
2: 成员变量:
可以有普通变量,还可以有常量 被final修饰的变量就是常量
3:成员方法:
可以有普通方法,还可以有抽象方法
注意:抽象类中可以没有抽象方法 ,抽象类是接口的前提
/*学员示例
具体事务:基本班学员,就业班学员
共性:姓名,学习,休假(holiday)
基本班学员
属性:姓名
行为:学习,休假(holiday)
就业班学员
属性:姓名
行为:学习,休假(holiday)
学生:(抽象的)
属性:姓名
行为:学习(抽象的)、休假(holiday)(抽象的)
*/
代码体现:
abstract class Student {
//成员变量
private String name;
//构造方法
public Student(){}
public Student(String name){
this.name = name;
}
//set / get方法
public void setName(Stringname){
this.name = name;
}
public String getName(){
return name;
}
//抽象方法
public abstract void study();
public abstract voidholiday();
}
class BaseStudent extends Student {
//构造方法
public BaseStudent(){}
public BaseStudent(Stringname){
super(name);
}
//父类方法重写
public void study(){
System.out.println("学习基础技术我很快乐");
}
public void holiday(){
System.out.println("2天一休真舒服");
}
}
class JobStudent extends Student {
//构造方法
public JobStudent(){}
public JobStudent(Stringname){
super(name);
}
//父类方法重写
public void study(){
System.out.println("学习高深技术很头疼");
}
public void holiday(){
System.out.println("3天一休我很困");
}
}
class AbstractTest2{
public static voidmain(String[] args) {
BaseStudent bs = newBaseStudent("张三");
bs.study();
bs.holiday();
JobStudent js = newJobStudent();
js.setName("李四");
js.study();
js.holiday();
}
}