面对对象编程语言有三类特性,分别是封装性、继承性以及多态性。
本节就来简单介绍下Java的继承。
一、继承的简单介绍、特点、规则
继承是多态的前提,如果没有继承,就没有多态。
继承主要解决的问题是:共性抽取(解决重复代码的问题)。
Java继承知识点里两个重要的名词:父类和子类
父类:也叫做基类、超类
子类:也叫派生类
Java继承关系当中的特点:
1、子类可以拥有父类的内容。
2、子类还可以拥有自己专有的内容。
子类方法的返回值必须小于等于父类方法的返回值范围。
Object类是所有类的公共最高父类(祖宗类)
java.lang.Object类是所有类的公共最高父类,java.lang.String就是Object的子类
子类方法的权限必须[大于等于]父类方法的权限修饰符
public > protected > (default) > private
这里(default)不是关键字default,而是什么都不写,留空。
在Java继承关系中,子类就是一个父类,也就是说,子类可以被当做父类看待
例如父类是员工,子类是讲师,那么讲师就是一个员工,关系is->a。
二、怎么来定义父子类之间的继承关系
一、定义父类的格式:(就是一个普通的类定义)
public class 父类名称
{
//...
}
二、定义子类的格式:
public class 子类名称 extends 父类名称
{
//...
}
注意:父类只能使用父类的东西,没有任何子类的内容。
子类既可以使用父类继承下来的东西,也可以用子类本身的东西。
1、在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式:
(1)直接通过子类对象访问成员变量
创建的时候等号左边是谁,就优先调用谁,没有则向上找(只能由子到父这样的顺序)
(2)间接通过成员方法访问成员变量
该方法属于谁,就优先调用谁,没有则向上找(只能由子到父这样的顺序)
2、在父子类的继承关系中,创建子类对象,访问成员方法的规则:
创建的对象是谁,就优先用谁,如果没有则向上找
注意事项:
无论成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的。
三、方法重写
概念:在继承关系当中,方法的名称一样,参数列表也一样。
方法重写和方法重载的区别:
方法重写是方法的名称一样,参数列表也一样,也就是覆盖、覆写。
方法重载是方法的名称一样,参数列表不一样
方法的覆盖重写特点:创建的是子类对象,则优先用子类方法。
@Override
可以把这个写在方法前面,用来检测是不是有效的覆盖重写,如果不是重写,会报错。(可选)
方法重写的应用场景:
设计原则:
对于已经投入使用类,尽量不要进行修改
推荐一个新的类,来重复利用其中共性内容,并且添加改动新内容。例如:
定义子类的xxx方法
void xxx()
{
super.xxx(); //把父类的xxx()方法拿过来重复利用
//子类再来添加更多内容。
xx();
xxxxx();
xxxxxxx();
}
继承关系中,父子类构造方法的访问特点:
1.子类构造方法当中有一个默认隐藏的super调用,所以一定是先调用的父类构造方法,再调用子类构造方法。
2.可以通过super关键字来子类构造调用父类重载构造。
3.只有子类构造方法,才能调用父类构造方法
4.super的父类构造调用,必须是子类构造方法的第一个语句,不能一个子类构造调用多次super构造。
总结:
子类必须调用父类构造方法,不写则赠送super();写了则用写了指定的super调用,super只能有一个,还必须是第一个。
父类的构造方法:(有参)
public xxx(int xx)
{
}
子类的构造方法:(无参)
public xxx()
{
super(10);
//..
//..
}
四、super关键字的用法
1、在子类的成员方法中,访问父类的成员变量。
System.out.println(super.xx);
2、在子类的成员方法中,访问父类的成员方法。
super.method();
3、在子类的构造方法中,访问父类的构造方法。
public simple_member(int Money_Balance , String Name)
{
super(Money_Balance,Name);
}
五、this关键字的三种用法
1、在本类的成员方法中,访问本类的成员变量。
2、在本类的成员方法中,访问本类的另一个成员方法。
3、在本类的构造方法中,访问本类的另一个构造方法。
在第三种用法中要注意:
this(...)调用也必须是构造方法的第一个语句,唯一一个
this(xxx);
super和this两种构造调用,不能同时使用
六、Java继承的特点
参考传智Java课程学习如下:
七、抽象
如果父类当中的方法不确定如何进行{}方法体实现,那么这就应该是一个抽象方法。
格式:
抽象方法:加上abstract关键字,然后去掉大括号,直接分号结束。
抽象类:抽象方法所在的类,必须是抽象类。
抽象类可以定义普通成员方法。
public abstract class xxx
{
//这是一个抽象方法,但是具体是什么,不确定。
public abstract void xxxx();
}
如何使用抽象类和抽象方法
1.不能直接创建new抽象类对象。
2.必须用一个子类来继承抽象父类。
3.子类必须覆盖重写父类当中所有的抽象方法。
覆盖重写(实现),去掉抽象方法的abstract关键字,然后补上方法大括号(实现)。
4.创建子类对象进行使用。
注意事项:
1.抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
2.抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
3.抽象类中,不一定包含抽象方法,但是有抽象方法的类就必须是抽象类。(应用:设计模式的适配器模式)
4.抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错,除非该子类也是抽象类。
下面来看一个Java继承的应用,发红包的案例:
用户类定义:
用户类主要定义了一些其它子类公有的信息,达到代码的复用功能。
package demo;
public class User {
//用户余额定义
private int Money_Balance ;
//用户名称定义
private String Name ;
public User(){
}
public User(int Money_Balance , String Name)
{
this.Money_Balance = Money_Balance ;
this.Name = Name ;
}
//获取成员名称
public String Get_Name()
{
return this.Name ;
}
//设置余额
public void Set_Money_Balance(int Money_Balance)
{
this.Money_Balance = Money_Balance ;
}
//获取余额
public int Get_Money_Balance()
{
return this.Money_Balance ;
}
//打印成员名称和余额
public void show()
{
System.out.println(this.Name+"有"+this.Money_Balance+"元钱");
}
}
群主类定义:
群主类主要实现的是发红包的方法。
package demo;
import java.util.ArrayList;
public class Lord extends User{
public Lord(int Money_Balance , String Name)
{
super(Money_Balance,Name);
}
//显示信息
public void show()
{
super.show();
}
//发红包的方法
public ArrayList<Integer> send(int totalMoney,int count)
{
ArrayList<Integer> list = new ArrayList<>();
int Integer_money = totalMoney / count ;
int remainder_money = totalMoney % count ;
//判断Lord有多少钱
if(totalMoney > super.Get_Money_Balance())
{
System.out.println("余额不足");
return list ;
}
//群主一共有多少钱,要发多少钱就从总数里扣掉这笔要发的钱
super.Set_Money_Balance(super.Get_Money_Balance()-totalMoney);
//总工要发count个红包
for(int i = 0 ; i < count ; i++)
{
//能够取整的
if(i < count - 1)
list.add(Integer_money);
//不能够取整的放在最后一个红包里
else
list.add(Integer_money+remainder_money);
}
return list;
}
}
普通成员类定义:
普通成员主要实现收红包的方法。
package demo;
import java.util.ArrayList;
import java.util.Random;
public class simple_member extends User{
public simple_member(int Money_Balance , String Name)
{
super(Money_Balance,Name);
}
//显示信息
public void show()
{
super.show();
}
//收红包的方法
public void receive(ArrayList<Integer> list)
{
Random r = new Random();
//得到一个ArrayList的随机索引
int rand_index = r.nextInt(list.size());
//获取员工当前有多少钱
int member_money = super.Get_Money_Balance();
//得到移除索引所对应的数值
int delet_money = list.remove(rand_index);
//并且得到的红包给员工本人,做加法
super.Set_Money_Balance(member_money+delet_money);
}
}
主程序编写:
package demo;
import java.util.ArrayList;
public class Red_envelopes_main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int money = 100 ;
Lord boss = new Lord(100,"老板");
simple_member worker1 = new simple_member(0,"员工1");
simple_member worker2 = new simple_member(0,"员工2");
simple_member worker3 = new simple_member(0,"员工3");
boss.show();
worker1.show();
worker2.show();
worker3.show();
//老板发红包
ArrayList<Integer> list_read = boss.send(20, 3);
boss.show();
//员工收红包
worker1.receive(list_read);
worker2.receive(list_read);
worker3.receive(list_read);
worker1.show();
worker2.show();
worker3.show();
}
}
运行结果: