类的继承
上节课我学了类与对象,我发现许多类是存在包含关系的。比如说学生类里可以包含大学生类,小学生类等等。而大学生类和小学生类中有一些属性与方法是和学生类中相同的,比如说姓名属性,年龄属性。然后我就在想在平常定义类的过程中是否可以简化呢,这种包含关系是否可以简化类的定义呢?在这节课中我终于找到了答案。
这节课的关键字就是继承,实现类与类的继承是要求类之间有包含关系的,比如说刚刚举得学生的例子。
Java实现继承需要用到extends,继承格式为:
public class 类名(子类,超类,派生类) extends 类名(父类,基类){
}
下面就牵扯到了子类到底继承了父类中的什么?
我们都知道类里面包括,属性,构造方法,普通方法,而且都会有访问修饰符修饰,那么子类继承了什么呢,是否还和访问修饰符有关呢?
答案是子类继承父类所有的属性和方法(普通方法构造方法)
但是私有的属性和方法不能调用,创建对象之后不能调用父类构造方法,在子类中可以调用父类的构造方法。
当父类和子类不在同一个包下时子类class能调用public 和 protected还有this(通配符)但是创建对象(第三方类)后,只能调用 public属性和方法。
还有一种情况就是子类和父类拥有的方法名相同,但是方法不一定完全一致,这里就涉及了方法的重载。关于重载我们在上一篇博客中已经提到。关于重载和重写的区别还有一点就是在Java里重写方法的左边有绿色三角标志。
然后就是自动转型的问题,这个我感觉也很有意思。举个例子:
假设很长时间没回家,走到离家还有点距离的地方,碰到你爸妈的一个朋友,看到你觉得你很像他的一个朋友,问:“你是不是xxx的儿子?”
xxx是 父母的名字:父类的对象名
儿子表示:子类的对象
(用父母的名字指向一个对象-儿子)
父类 对象名 = new 子类构造方法(); (new关键词开辟内存)
这里也要特别注意对象名前面一定得是父类。
下面再设定一个场景,让我们由代码表示出来:这个和第一篇博文中差不多
奥特曼可以攻击小怪兽或者美国队长,直到一方血量为0时,结束战斗谁胜!
这个的话我们可以给奥特曼类写两个攻击方法,一个是攻击小怪兽的,一个是攻击美国队长的。但是试想一下,要是奥特曼攻击的对象特别多的话,那一个一个写的话就太麻烦了。我们通过观察发现小怪兽和美国队长都有共同的属性方法,那么我们是否可以创建一个父类让他们继承呢,然后向奥特曼攻击方法里传入父类的参数,在通过自动转型创建子类对象传入奥特曼的攻击方法里呢?答案是肯定的,这就体现了继承的优点。
奥特曼类:
/创建一个奥特曼类,包括其name,blood,attack,defence基本属性
//还包括一个与角色类的pk方法
publicclass ATM {
//设置基本属性
private String name;//姓名
privateintblood;//血量
privateintattack;//攻击力
privateintdefence;//防御力
//构造方法
public ATM(String n,int blood,int attack,int defence){
name=n;
this.blood=blood;
this.attack=attack;
this.defence=defence;
}
//对于属性的set和get方法
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getBlood() {
returnblood;
}
publicvoid setBlood(int blood) {
this.blood = blood;
}
publicint getAttack() {
returnattack;
}
publicvoid setAttack(int attack) {
this.attack = attack;
}
publicvoid setDefence(int d){
defence=d;
}
publicint getDenfence(){
returndefence;
}
//pk方法,首先判断奥特曼攻击力是否大于角色类防御力,如大于则造成伤害,否则无法对角色类造成伤害
//奥特曼的攻击力减去角色类的防御力等于怪奥特曼兽对角色类造成的伤害
//角色类原本的血量减去伤害值即为pk过后剩余血量,此时输出剩余血量
publicvoid pk(Role R){
if(attack>R.getDefence()){
R.setBlood(R.getBlood()-(attack-R.getDefence()));
System.out.println(name+"攻击了"+R.getName()+","+R.getName()+"剩余血量为:"+R.getBlood());
}else{
System.out.print(name+"打不过"+R.getName()+",无法对其造成伤害");
}
}
}
父类角色类:
//创建一个角色类作为父类,被怪兽类和美国队长类继承
//此类包括name,blood,attack,defence基本属性
//此类包括一个与奥特曼pk的方法
publicclass Role {
//设置基本属性
private String name;//名称
privateintblood;//血量
privateintattack;//攻击力
privateintdefence;//防御力
//设置属性的set和get方法
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getBlood() {
returnblood;
}
publicvoid setBlood(int blood) {
this.blood = blood;
}
publicint getAttack() {
returnattack;
}
publicvoid setAttack(int attack) {
this.attack = attack;
}
publicvoid setDefence(int d){
defence=d;
}
publicint getDefence(){
returndefence;
}
//pk方法,首先判断角色类攻击力是否大于奥特曼防御力,如大于则造成伤害,否则无法对奥特曼造成伤害
//角色类的攻击力减去奥特曼的防御力等于角色类对奥特曼造成的伤害
//奥特曼原本的血量减去伤害值即为pk过后剩余血量,此时输出剩余血量
publicvoid pk(ATM atm){
if(attack>atm.getDenfence())
{
atm.setBlood(atm.getBlood()-(attack-atm.getDenfence()));
System.out.println(name+"攻击了"+atm.getName()+","+atm.getName()+"剩余血量为:"+atm.getBlood());
}else{
System.out.print(name+"打不过"+atm.getName()+",无法对其造成伤害");
}
}
}
小怪兽类:
package com.hnu.yc0710;
//创建一个怪兽类作为子类,继承父类角色类
publicclass Monster extends Role{
}
美国队长类:
ackage com.hnu.yc0710;
//创建一个美国队长类为子类,继承Role类并且对父类中pk方法进行重写。
publicclass UScaptain extends Role{
publicvoid pk(ATM atm){
System.out.println("美国队长与奥特曼大队达成协议,对奥特曼打不还手,本着维护世界和平的原则,双方互不侵犯,共同打击小怪兽!");
}
}