Java 继承
目录
1. 继承概述
举例:Person 类中有name,age 等属性和方法,而 Couster 类,Student 类,Wait 类也具有相同的属性和方法 ,为了减少代码的冗余,可以使用 extents 关键字从 Person 类中获取并直接使用方法和属性。即为继承;
2. 继承好处
1. 减少代码冗余,提高代码的复用性;
2. 方便功能的扩展;
3. 为后面多态的学习提供前提;
3. 继承格式
格式:Class A extends B { }
A :子类,派生类;
B:超类,父类,基类;
体现:
(1)子类继承父类,子类就会获得父类的属性和方法,
对于父类私有的属性和方法,子类也可以继承,但不能直接调用;
(2)子类继承父类之后,还可以声明自己独特的属性和方法,实现功能的扩展;
class A{
String name;
private int age;
public A(){};
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
private void show(){
System.out.println("快乐一万年");
}
public void See(){
show();
}
}
class B extends A {
public void eat(){
System.out.println("这是子类自己生声明的方法");
}
public static void main(String[] args) {
// 子类 B 会继承父类 A 的结构:属性,方法;
B b = new B();
b.name="吕小布";
System.out.println(b.name);
// 私有属性亦可继承,但不能直接调用,须借助set/get方法
b.setAge(100);
System.out.println(b.getAge());
// 私有方法也可继承,但不能如此直接调用:b.show()
b.See();//通过继承父类公共权限的方法间接调用
// private void show(){
// System.out.println("快乐一万年");
// }
// public void See(){
// show();
// }
b.eat();
}
}
4. 继承规定
1. Java 中允许多层继承,不允许多重继承;
2. 一个类可以被多个类继承;
3. 单继承性:一个类只有一个父类;
4. 子类直接继承的类称为直接父类,
间接继承的类称为间接父类,
同时也获取了直接父类与间接父类的所有属性和方法;
5. 所有的类都直接继承或间接继承 java.lang.Object 类;
5. debug 调试
step into 无法进入方法:
6. 方法重写
6.1 概述
子类继承父类的所有属性和方法后,子类可能会根据其需求对父类同名同参的方法的方法体进行修改,进而覆盖夫类的方法,这就是方法重写(override)。
子类调用方法时,会调用子类中重写的方法,父类中的方法被重写方法覆盖;
public class Annimal {
public void eat(){
System.out.println("生物得吃饭啊");
}
}
class dog extends Annimal{
// 方法重写:子类继承父类了方法,又根据其需要修改方法体;
public void eat(){
System.out.println("狗爱吃骨头");
}
public static void main(String[] args) {
dog d = new dog();
d.eat();
}
}
6.2 规定
格式:权限修饰符 返回值类型 方法名( 参数列表 ){ 方法体 }
1. 权限修饰符:子类的权限修饰符不得低于父类,但父类的私有方法不可以被重写;
2. 返回值类型:子类重写的方法的的返回值类型需要和父类被重写的方法保持一致;
但若父类返回值类型为引用类型,子类返回值类型可以相同,也可以是该引用类型的子类,
如父类返回值类型为 Object ,子类重写的方法的返回值应为 Object 或其子类,如 String 等;
3. 重写方法的方法名与参数列表必须与父类保持一致;
4. 子类重写的方法抛出的异常不大于父类被重写的方法抛出的异常;
5. 子类与父类同名同参的方法要么都声明为 static (无法覆盖,不允许重写),
要么都声明为 非static (允许重写);
在实际使用中,可以将父类被重写的方法直接复制到子类中重写方法的位置,接着修改其方法体即可,一定不会重写方法出错;
7. super 关键字
7.1 概述
继承关系中,子类的属性不会被父类的属性覆盖。
因此,在调用父类、子类重名的属性或者调用父类被重写的方法(也可以认为方法重名)时,为便于区分,需要使用 super 关键字;
即,super 如同 this,解决重名的问题;
7.2 使用
1. super 可修饰属性、方法、构造器;
2. super.属性/方法/构造器 相当于 父类的属性/方法/构造器,即 super == 父类;
class F{
int age = 18;
String name = "小布";
public void eat(){
System.out.println("吃东西可以补充营养");
}
}
class Z extends F{
String name = "吕小布";
// 方法重写
public void eat(){
System.out.println(super.name);//子类中调用父类的同名属性
System.out.println("不可以不吃饭");
super.eat(); //子类中调用父类被重写的方法;
}
public static void main(String[] args) {
Z z = new Z();
System.out.println(z.name);//父类,子类的属性不会覆盖;
z.eat();
// 吕小布
// 小布
// 不可以不吃饭
// 吃东西可以补充营养
}
}
7.3 在构造器中使用
1. 父类属性没有私有化;子类构造器中可以使用 this. ;
2. 父类属性私有化;子类构造器中可以使用 super ;
3. this. 与 super() 只能放在子类构造器的首行;
4. 但是,父类属性非私有化时,this. 与 super() 只能使用其中一个;
5. 子类构造器没有显式的使用 this. 或 super( ) ,则默认使用父类的空参构造器,
因此父类的空参构造器一定要写;
6. 在子类的多个构造器中,至少有一个构造器使用了 super( ),调用了父类的空参;
8. 子类对象实例化的全过程
从结果上看:子类继承父类,就会获得父类(直接父类与间接父类)所有的方法和属性;
从过程上看:通过子类构造器创建子类的对象时,一定会直接或间接调用父类的构造器,进而调用父类的父类的构造器,一直到 Java.long.Object 为止,获得所有父类(直接和间接父类)的所有属性和方法;
9. 练习
public class Account {
private int id;//账号
private double balance;//余额
private double annualinterestRate;//年利率
public Account(){};
public Account(int id,double balance,double annualinterestRate){
this.id = id;
this.balance = balance;
this.annualinterestRate = annualinterestRate;
}
public void setId(int id){
this.id = id;
}
public int getId(){
return id;
}
public void setBalance(double balance){
this.balance = balance;
}
public double getBalance(){
return balance;
}
public void setAnnualinterestRate(double annualinterestRate){
this.annualinterestRate = annualinterestRate;
}
/*返回月利率方法* */
public double getMonthlyInterest(){
return annualinterestRate/12;
}
/*取款方法* */
public void withdraw(double amount){
if(amount <= balance){
balance -=amount;
System.out.println("取款成功!");
}else
System.out.println("取款失败!\n"+"余额为"+balance+"元");
} /*存款方法* */
public void deposit(double sum){
balance += sum;
System.out.println("存款成功!");
}
}
class CheckAccount extends Account{
private double overdraft;//可透支限额
public CheckAccount(int id,double balance,double annualinterestRate,double overdraft){
super(id,balance,annualinterestRate);
this.overdraft = overdraft;
}
public void setOverdraft(double overdraft){
this.overdraft = overdraft;
}
public double getOverdraft(){
return overdraft;
}
// 核心代码均在此重写方法中
@Override
public void withdraw(double amount){
// 不可以使用 super 调用父类私有的属性,因为 super 解决的是重名问题,并不能解决封装问题;
// if(amount <= (super.getBalance() + overdraft)){}
if(amount <= getBalance()){
// setBalance(getBalance()-amount);//与下方代码功能相同
super.withdraw(amount);//调用父类的方法;
}else if(overdraft >= amount-getBalance()){//算术运算符优先级大于逻辑运算符
overdraft -=(amount-getBalance());
setBalance(0.0);
}else System.out.println("超过可透支金额!");
}
}
class CheckAccountTest{
public static void main(String[] args) {
CheckAccount ca = new CheckAccount(200022,6000,0.031,1000);
ca.withdraw(8000);
System.out.println("您的帐户余额:"+ca.getBalance());
System.out.println("可透支余额:"+ca.getOverdraft());
}
}
原文地址:https://blog.csdn.net/m0_74012211/article/details/145067662
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!