java中的继承(Extends)

继承(Extends)

1.什么是继承,有什么用?

  • 继承:在现实生活中也是存在的,例如:父亲很有钱,儿子不用努力也很有钱。
  • 继承有什么用:
    • 基本作用:子类继承父类,代码可以得到复用。(这个不是重要作用,是基本作用。
    • 主要(重要)作用:因为有了继承关系,才有了后期的方法覆盖多态机制。
  • 相关代码:
/* file:ExtendsTest02.java */

// 使用继承机制来解决代码复用问题
public class ExtendsTest02 {
    public static void main(String[] args) {
        // 创建普通账户
        Account act = new Account();
        act.setActon("11111111");
        act.setBalance(10000);
        System.out.println(act.getActon() + ",余额" + act.getBalance());

        // 创建信用账户
        CreditAcccount ca = new CreditAcccount();
        ca.setActon("22222222");
        ca.setBalance(-10000);
        ca.setCredit(0.99);
        System.out.println(ca.getActon() + ",余额" + ca.getBalance() + ",信誉度" + ca.getCredit());
    }
}

// 银行账户类
// 账户属性:账号、余额
class Account { // 父类
    // 属性
    private String acton;
    private double balance;

    // 构造方法
    public Account() {

    }
    public Account(String actno, double balance) {
        this.acton = actno;
        this.balance = balance;
    }

    // setter and getter
    public void setActon(String acton) {
        this.acton = acton;
    }
    public String getActon() {
        return acton;
    }
    public void setBalance(double balance) {
        this.balance = balance;
    }
    public double getBalance() {
        return balance;
    }
}

// 其他类型的账户:信用卡账户
// 账号、余额、信誉度
class CreditAcccount extends Account {  // 子类
    // 属性
    private double credit;

    // 构造方法
    public CreditAcccount() {

    }

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


2.继承的相关特性

  • ①B类继承A类,则称A类为超类(superclass)、父类、基类,B类则称为子类(subclass)、派生类、扩展类。
class A{}	// 父类
class B extends A {}	// 子类
  • 我们平时聊天说的比较多的是:父类和子类。
  • superclass 父类
  • subclass 子类
  • ② java 中的继承只支持单继承不支持多继承, C++中支持多继承, 这也是 java 体

现简单性的一点,换句话说,java 中不允许这样写代码:

class B extends A,C{ }	// 在java中不允许这样写代码
  • ③ 虽然 java 中不支持多继承,但有的时候会产生间接继承的效果, 例如:
  • ④ java 中规定,子类继承父类,除构造方法不能继承之外,剩下都可以继承。但是私有的属性无法在子类中直接访问。(父类中private修饰的不能在子类中直接访问。可以通过间接的手段来访问。)
  • ⑤ java 中的类没有显示的继承任何类, 则默认继承object类,object类是 java 语言

提供的根类(老祖宗类),也就是说,一个对象与生俱来就有object类型中所有的特征。

  • ⑥ 继承也存在一些缺点,例如:CreditAccount 类继承 Account 类会导致它们之间的

藕合度非常高,Account 类发生改变之后会马上影响到CreditAccount 类

  • 相关代码:
/* file:ExtendsTest03.java */
class A {

}


class B { 

}

class C extends A { 

}

class D extends B {

}

// 语法错误
// java 只允许单继承。 不允许多继承。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
*/ 

3.子类对象调用父类方法!??

  • 测试:子类继承父类之后,能使用子类的对象调用父类的方法吗?
    • 可以,因为子类继承了父类之后,这个方法就属于子类了。当然可以是有子类对象来调用。
  • 相关代码:
/* 
    测试:子类继承父亲之后,能使用子类对象调用父类方法吗
        实际上以上这问题问题问的有点蹊跷!!!!
        哪里蹊跷?“能使用子类对象调用父类方法”
        本质上,子类继承父类之后,是将父类继承过来的方法桂自己所有。
        实际上调用的也不是服了的方法,是他子类自己的方法(因为已经继承过来了,就属于自己的。)
*/ 
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 = "XiaoHua";    // 默认值不是一个null,给一个XiaoHua

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

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

}

4.什么时候使用继承?

  • 在实际开发中,满足什么条件的时候,我可以使用继承?
    • 凡是采用 ”is a“ 能描述的,都可继承
    • 例如:
      • Cat is a Animal:猫是一个动物
      • dog is a Animal:狗是一个动物
      • CreditAccunt is a Account:信用看卡账户是一个银行账户
      • ……
    • 假设以后的开发中有一个A类,有一个B类,A类和B类确实也有重复的代码,那么他们两个之间就可以继承吗?不一定,还是要看一看它们之间是否能够使用 is a 来描述。
class Customer {// 顾客类
	String name; 	// 名字
    // setter and getter
}

class Product {// 商品类
    String name;	// 名字
    // setter and getter
}

class Product extends Customer {
    
}

// 以上这个继承就属于很失败的!因为:Product is a Customer,是有违伦理的。

5.Object类

  • 任何一个类,没有显示继承任何类,默认继承Object,那么Object类当中有哪些方法呢,老祖宗为我们提供了哪些方法?
    • 经常看看JDK的源代码(多看看牛人写的程序自己才会变成牛人。)先模仿后超越
    • java为啥好学?
      • 是因为java内置了一套庞大的类库,程序员不需要从0开始写代码,程序员可以基于这套庞大的类库进行“二次”开发。(开发速度较快,因为JDK内置的这套库实现了很多基础的功能。)
        • 例如:String是SUM编写的字符串类、System是SUM编写的系统类。这些类可以直接拿来使用。
    • JDK源代码在什么位置?
      • 在你下载的java的jdk目录下的 lib目录下的 src.zip中。
        • 我这里是:D:\JDK\jdk-17.0.5\lib\src.zip
    • 现在可以看懂一下代码嘛?
       System.out.pringln("Hello World!");
    
    • 以上代码分析:
      • System.out 后面**没有小括号,**说明 **out **是 变量名。
      • 另外 System 是一个类名,直接使用类名 System.out ,说明 out是一个静态变量
      • System.out 返回一个对象,然后采用”对象.“的方式访问 println()方法。
      • 我们来**模拟一个 **System.out.pringln(); 代码如下:
/* file:Test.java */ 
// 模拟 System.out.println();
public class Test {
    public static void main(String[] args){
        // 系统自带的输出函数
        System.out.println("Hello World!");
        // 自己模拟写的输出函数
        system.Out.Println("Hello World!");
    }
}

// 模拟 System 类
class system {
    static Out Out = new Out();
}

// 模拟 out对象的类
class Out {
    
    // 模拟 println() 方法
    public void Println(String s) {
        System.out.println(s);
    }
}

Object类中的源代码(继承结束)

  • 我们研究了一下Object类当有很多方法,大部分都看不懂,其中有一个叫做**toString()**的方法,我们进行了测试,发现:
    • System.out.pringln(引用);
    • 当直接输出一个"引用"的时候,println()方法会先自动调用"引用.toString()",然后输出toString()方法的执行结果 。
  • 相关代码:
/*
package java.lang;

import jdk.internal.vm.annotation.IntrinsicCandidate;


public class Object {
    // 无参数构造方法
    @IntrinsicCandidate
    public Object() {}
    
    // 底层调用C++
    @IntrinsicCandidate
    public final native Class<?> getClass();
    
    // 注意:当源代码中一个方法以“;”结尾,且修饰符列表中有“native”关键字
    // 表示底层调用 C++写的dll程序(dll动态链接库文件)
    @IntrinsicCandidate
    public native int hashCode();
    
    // 已有对象A,想创建一个 A 一模一样的对象,你可调用这个克隆方法。
    // 底层也是调用C++
    // equals 方法你应该能看懂。
    // boolean 是方法的返回值类型
    // equals 是一个方法名:相等
    //(object obj)形参
    //只不过目前还不知道这个方法存在的意义。
    public boolean equals(Object obj) {
        return (this == obj);
    }
    
    @IntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;
   
    //一会我们可以测试一下tostring()方法。
    // public表示公共的
    //string是返回值类型,tostring()方法执行结束之后返回一个字符串。
    // tostring 这是方法名。
    //()表示形参个数为0
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
   
    @IntrinsicCandidate
    public final native void notify();
    
    @IntrinsicCandidate
    public final native void notifyAll();
    
    public final void wait() throws InterruptedException {
        wait(0L);
    }

    public final native void wait(long timeoutMillis) throws InterruptedException;
    
    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }

    @Deprecated(since="9")
    protected void finalize() throws Throwable { }
}
*/

public class ExtendsTest05 {
    // ExtendsTest05默认继承object
    // ExtendsTest05类当中是有toString()方法
    //不过tostrina(O方法是一个实例方法,需要创建对象才能调用。
    /*
    public string tostring() {
    return getClass() .getName () + "g" + Integer.toHexString (hashCode ());
    */

    public static void main(String[] args) {
        // 分析这个代码可以执行吗?
        //ExtendsTest05.toString();

        // 先new对象
        ExtendsTest05 et = new ExtendsTest05();
        String retValue = et.toString();

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

        //创建对象
        Product pro = new Product () ;

        String retValue2 = pro.toString() ;
        System.out.println(retValue2); // Product05305068a
        //以上两行代码能否合并为一行!!!可以
        System.out.println(pro.toString()); //Product05305068a
        //如果直接输出引用"呢???????
        System.out.println(pro); //Product€5305068a
        System.out.println(100);
        System.out.println(true) ;
        //Product05305068a
        System.out.println(pro); // println方法会自动调用pro的toString()方法。
    }
}

class Product {
    /*
    public string toString() {
    return getClass() .getName () + "e" + Integer.toHexString(hashCode());
    }
    */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值