继承
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
1.关键字: extends(extends: 子类是在父类的基础上,对属性或者方法进行扩展得到的新类。)
(super 与 this 关键字:
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。)
2.格式: public class 子类名 extends 父类名{ }
3.举例:
学生类:
属性:姓名、学号、学分、性别
方法:学习
大学生类:
属性:姓名、性别、学号、学分、专业
方法:学习
大学生和学生属于继承关系。
4.为什么需要继承?
以学生类为例:如大学生和中学生
大学生:属性(姓名,性别,学号,学分),方法(学习)
中学生:属性(姓名,性别,学号),方法(学习)
两个类的代码存在重复,导致后果就是代码量大且臃肿,而且维护性不高(维护性主要是后期需要修改的时候,就需要修改很多的代码,容易出错),所以要从根本上解决这两段代码的问题,就需要继承,将两段代码中相同的部分提取出来组成 一个父类:学生类。
这个学生类就可以作为一个父类,然后大学生类和中学生类继承这个类之后,就具有父类当中的属性和方法,子类就不会存在重复的代码,维护性也提高,代码也更加简洁,提高代码的复用性。(复用性主要是可以多次使用,不用再多次写同样的代码)
5.继承类型
java中的继承是单继承模式,不支持多继承,但支持多重继承。
6.继承的特点
(1)子类拥有父类非 private 的属性、方法。
(2)子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
(3)子类可以用自己的方式实现父类的方法。
(4)Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
(5)提高了类之间的耦合性。(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)
(6)Object是所有其他类的父类。
提到继承,需要了解java的访问权限。
访问权限
Java语言中有4中访问修饰符:friendly(缺省)、private、public和protected。
public :能被所有的类(接口、成员)访问。
protected:只能被本类、同一个包中的类访问;如果在其他包中被访问,则必须是该成员所属类的子类。
friendly(缺省):访问权限与protected相似,但修饰类成员时不同包中的子类不能访问。
private:成员变量和方法都只能在定义它的类中被访问,其他类都访问不到。对成员变量的进行获取和更改,一般用get(),set() ,public 方法。实现了Java面向对象的封装思想。
子类继承父类的时候,能拥有所有的属性和方法,但是限于访问权限,部分属性和方法不能直接使用。
所谓的访问,有两种方式,直接访问和通过对象访问。
在与父类不同包的子类中,通过父类的对象实例只能访问父类的public成员,不能访问protected成员。
重写或者实现方法时,访问权限必须比父类大。
重写与转型
1.重写:父类的方法不能满足子类的需要,子类可以覆盖父类的方法。
当子类需要父类的功能,而子类有新的内容,可以重写父类中的方法。在实际开发过程中,随着代码量的逐渐增加,维护成了一个很大的问题,如果需要对某个方法进行修改,其本身代码以及其子类代码都会受到影响,而重写则很好的解决了这个问题。方法重写又称为方法覆盖、方法复写。
(1)必须要有继承关系
(2)父类的方法在子类中可以访问。
(3)方法的声明,访问权限可以扩大,方法返回值类型、方法名、参数必须一致。
注:重载:方法名相同,但是参数不一样。
2.自动转型:
子类对象可以自动的变为父类。自动转型后,方法调用的内容以子类为准。
实例
美国队长和钢铁侠互相PK,采用回合制,每次攻击让对方的血量减少,减少量攻击方的攻击值。重复,直到某一方的血量小于等于0结束。 胜利的一方继续和灭霸PK,灭霸每次攻击,让对方的血量减少,减少量为灭霸的两倍攻击值,重复,直到某一方的血量小于等于0结束。
输出:战斗的过程、结果
要求:每个类至多有一个攻击方法。
//Player类
package pkpk;
public class Player {
public int attack;
public int blood;
publicvoidbattle(Playerp) {
//血量=血量-攻击值
p.blood=p.blood-attack;
System.out.println("对方剩余血量为"+p.blood);
}
}
//钢铁侠类
package pkpk;
publicclassIronManextendsPlayer{
publicvoidbattle(Playerp) {
p.blood=p.blood-attack;
System.out.println("钢铁侠正在攻击,对方剩余血量为"+p.blood);
if(p.blood<=0) {
System.out.println("钢铁侠获胜!");
}
}
}
//美国队长类
package pkpk;
publicclassCaptainAmericaextendsPlayer{
publicvoidbattle(Playerp) {
//血量=血量-攻击值
p.blood=p.blood-attack;
System.out.println("美国队长正在攻击,对方剩余血量为"+p.blood);
if(p.blood<=0) {
System.out.println("美国队长获胜!");
}
}
}
//灭霸类
package pkpk;
public class Boss extends Player{
publicvoidbattle(Playerp) {
p.blood = p.blood - attack*2;
System.out.println("灭霸正在攻击,对方剩余血量为"+p.blood);
if(p.blood<=0) {
System.out.println("灭霸获胜!");
}
}
}
//实现战斗
package pkpk;
public class Mainer {
publicstaticvoidmain(String[]args) {
//创建对象
CaptainAmericamei=newCaptainAmerica();
mei.attack=100;
mei.blood=5000;
IronMangang=newIronMan();
gang.attack=60;
gang.blood=8000;
Bossmie=newBoss();
mie.attack=80;
mie.blood=9000;
System.out.println("美国队长与钢铁侠战斗!");
while(mei.blood>0 &&gang.blood>0) {
mei.battle(gang);
if(gang.blood>0) {
gang.battle(mei);
}
}
System.out.println("美国队长血量为"+mei.blood+",钢铁侠血量为"+gang.blood);
if(mei.blood>0) {//美国队长与灭霸继续
System.out.println("美国队长与灭霸继续战斗!");
while(mei.blood>0 &&mie.blood>0) {
mei.battle(mie);
mie.battle(mei);
}
}
else {//钢铁侠与灭霸继续
System.out.println("钢铁侠与灭霸继续战斗!");
while(gang.blood>0 &&mie.blood>0) {
gang.battle(mie);
mie.battle(gang);
}
}
}
}