第十二章 继承

1 继承extends

1.1 什么是继承,有什么用

继承:在现实世界当中也是存在的,例如:父亲很有钱,儿子不用努力也很有钱。
继承的作用:
基本作用:子类继承父类,代码可以得到复用。(这个不是重要的作用,是基本作用)
主要作用:因为有了继承关系,才有了后期的方法覆盖和多态机制。

ExtendsTest01.java


/*
银行账户类
账户的属性:账户、余额
*/

// 分析以下程序存在什么问题?
public class ExtendsTest01{
public static void main(String[] args){
Account act = new Account();
act.setActno("11111111");
act.setBalance(100000000);
System.out.println(act.getActno() + ", 余额" + act.getBalance());

CreditAccount ca = new CreditAccount();
ca.setActno("2222222");
ca.setBalance(11110000);
ca.setCredit(1.28);
System.out.println(ca.getActno() + ", 余额" + ca.getBalance() + ", 信誉度" + ca.getCredit());
}
}

class Account{  // 父类
// 属性
private String actno;
private double balance;

// 构造方法
public Account(){}
public Account(String actno, double balance){
this.actno = actno;
this.balance = balance;
}

public void setActno(String actno){
this.actno = actno;
}
public String getActno(){
return actno;
}
public void setBalance(double balance){
this.balance = balance;
}
public double getBalance(){
return balance;
}

}

// 其它类型的账户:信用卡账户
class CreditAccount extends Account{  // 子类
// 属性
private double credit;

// 构造方法
public CreditAccount(){

}

public void doSome(){
// 错误:actno在Account中是private访问控制
// System.out.println(actno);
// 单间访问
System.out.println(getActno());
}

// settter and getter方法
public void setCredit(double credit){
this.credit = credit;
}
public double getCredit(){
return credit;
}
}

 

 

1.2 继承的相关特性

1 B类继承A类,则称A类为超类(superclass)、父类、基类,B类则称为子类(subclass)、派生类、扩展类。

2 java 中的继承只支持单继承,不支持多继承,C++中支持多继承,这也是java体现简单性的一点,换句话说,java中不允许这样写代码: class B extends A,c{ }

3 虽然java中不支持多继承,但有的时候会产生间接继承的效果,例如: class C extends B,class B extends A,也就是说,C直接继承B,其实C还间接继承A。

4 java中规定,子类继承父类,除构造方法不能继承外,剩下都可以继承,但是私有的属性无法在子类中直接访问。(父类中private修饰的不能在子类中直接访问,可以通过间接的手段来访问)

5 java中的类没有显示的继承任何类,则默认继承object类,object类是 java 语言提供的根类(老祖宗类),也就是说,一个对象与生俱来就有object类型中所有的特征。

6 继承也存在一些缺点,例如:creditAccount类继承Account类会导致它们之间的耦合度非常高,Account类发生改变之后会马上影响到creditAccount类


class A{

}

class B{

}

class C extends A{

}

class D extends B{

}

// 语法错误
// java只允许单继承。不允许多继承。C++支持多继承。
// C++更接近现实一些。因为在现实世界中儿子同时继承父母两方的特征
/*
class E extends A, B {

}
*/

class X{

}

class Y extends X {

}

// 其实这也说明了Z是继承X和Y的。
// 这样描述:Z直接继承了Y,Z间接继承了X
class Z extends Y {

}

/*
Z继承了Y
Y继承了X
X继承了Object

Z对象具有Object类的特征(基因)。

Object是所有类的超类。类体系结构中的根。
java这么庞大的一个继承结构,最顶点是:Object
*/

 

 

1.3 继承的使用

测试:子类继承父类之后,能使用子类调用父类方法吗
本质上:子类继承父类之后,是将父类继承过来的方法归自己所有。
实际上调用的也不是父类的方法,是子类自己的方法。(因为已经继承过来了,就属于自己的)

在实际开发中,满足什么条件的时候,我可以使用继承呢?
凡是采用“is a”能描述的,都可以继承。
例如:
Cat is a Animal
Dog is a Animal
CredicAccount is a Account
...

假设以后的开发中有一个A类,有一个B类,A类和B确实也有重复代码,那么他们两个之间就可以继承吗?不一定,还是需要看一看它们之间是否能够用“is a”来描述。
class Customer{
String name;  // 名字
}
class Product{
String name;  // 名字
}
class Product extends Customer{

}
以上的继承就属于很失败的

JDK 源代码在什么位置:
"F:\Dev\Java\jdk-16.0.2\lib\src"

你现在能看懂以下代码了吗?
System.out.println("Hello World!");
System.out 中,out后面没有小括号,说明out是变量名。
另外System是一个类名,直接使用类名System.out,说明out是一个静态变量。
System.ou 返回一个对象,然后采用“对象.”的方式访问println()方法。

我们研究了一下Object类当中有很多方法,大部分看不懂,其中有一个叫做toString()的,我们进制了测试,发现:
System.out.println(引用);
当直接输出一个“引用”的时候,println()方法会直接自动调用“引用.toString()”,然后toString方法的执行结果。



public class ExtendsTest04{
public static void main(String[] args){

// 创建子类对象
Cat c = new Cat();
// 调用方法
c.move();
// 通过子类对象访问name可以吗?
System.out.println(c.name);
}
}

class Animal{
// 名字
String name = "小花";

// 提供一个动物移动的方法
public void move(){
System.out.println(name + "正在移动");
}
}

// Cat子类
// Cat继承Animal,会将Animal中所有的全部继承过来。
class Cat extends Animal{

}

/*
System.out.println("Hello World!");
以上代码中:System、out、println都是标识符。
*/

public class Test{

// 静态变量
static Student stu = new Student();

// 入口
public static void main(String[] args){
Test.stu.exam();
}
}

class Student{

// 实例方法
public void doSome(){
System.out.println("考试......");
}
}
public class ExtendsTest05{

   // ExtendsTest05默认继承Object
   // ExtendsTest05类当中是有toString()方法
   // 不过toString()方法是一个实例方法,需要创建对象才能调用。        

   public static void main(String[] args){

       // 分析这个代码可以执行吗?
       // ExtendsTest05.toString();

       // 先new对象
       ExtendsTest05 et = new ExtendsTest05();
       String retValue = et.toString();
       System.out.println(retValue);  // ExtendsTest05@24d46ca6

       // 24d46ca6 可以“等同”看做对象在堆内存当中的内存地址。
       // 实际上是内存地址经过“哈希算法”得出的十六进制结果。
       System.out.println(retValue);  // ExtendsTest05@24d46ca6

       // 创建对象
       Product pro = new Product();
       String retValue2 = pro.toString();
       System.out.println(retValue2);  // Product@372f7a8d
       // 以上两行代码合并成为一行
       System.out.println(pro.toString());  // Product@372f7a8d
       System.out.println(pro);  // Product@372f7a8d

  }
}

class Product{

}
 
posted @   路走  阅读(132)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示