java面向对象类的继承~ 匿名类 ;多态特性;强制类型转换

类的继承

创建子类语法:

    修饰符 class 子类名 extends 父类名{
    
    }

匿名子类语法:

直接实例化,过程中通过匿名类 继承父类,在实例化过程中将子类匿名

<父类类名>  实例名 = new 父类名()  {

  匿名类代码逻辑....

}

自定义类默认继承了Object类:

    自定义类默认隐藏式继承了Object类
    class Cat {
    ...
    }
    等价于如下
    class Cat extends Object{
    .........
    }

    类的继承特性:

        1、没指定继承哪个父类,默认继承Object
        2、在Java中Object类是所有类的父类
        3、子类继承父类时,不能继承父类的构造方法【这一点不如Python】
        4、父类叫做基类,子类叫做派生类
        5、满足条件is a
        6、一个类只能继承一个直接父类
        7、类继承具有传递性。

理解视图举例

 

 

代码举例:水果~苹果

父类:水果

package com.zmd.study.exten;

public class Fruit {
    /**
     * 水果的重量属性
     */
    private double weight ;

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
}

 

子类:苹果类

package com.zmd.study.exten;

public class Apple extends Fruit{
    public String color ;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

测试类输出:

public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        apple.setWeight(0.3);
        System.out.println("苹果重量:" + apple.getWeight());
    }  
}

/**
输出:
苹果重量:0.3
*/

 重写父类方法

    ---子类的方法名、参数列表、修饰符一致
    ---子类的返回类型一致或父类方法返回类型的子类型:
        例如:String 是Object的子类型
            int 是 Double的子类型

super

    注意事项:
        1、super.方法/变量。直接访问父类的资源
        2、如果不写,默认为访问本类中资源即隐含了this.
        3、如果子类重写父类的方法体中,有调用被重写的方法,则只能使用super
        4、访问父类中的实例变量可以是this. 也可以是super. 但是范围子类独有的实例变量/方法 只能用this
        5、super(); super([参数列表])完成对父类构造方法赋值

重写的方法无返回值测试

水果父类

package com.zmd.study.exten;

/**
 * @ClassName Fruit
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/3/28.
 */
public class Fruit {
    /**
     * 水果的重量属性
     */
    private double weight ;

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
    public void showInfo(){
        //被子类重写的方法
        System.out.println("我是水果,我的重量是:" + weight );
    }
}

子类

package com.zmd.study.exten;

import java.sql.SQLOutput;

/**
 * @ClassName Apple
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/3/28.
 */
public class Apple extends Fruit{
    public String color ;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public void showInfo(){
        //调用父类中的方法用super
        super.showInfo();
        System.out.println("我是苹果,我的重量是:" + this.getWeight());
    }
}

测试类&执行效果

import com.zmd.study.exten.Apple;

public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        apple.setWeight(0.2);
        apple.showInfo();
    }
}
/**
输出:
我是水果,我的重量是:0.2
我是苹果,我的重量是:0.2
*/

子类和父类的属性名相同

如果在子类中定义了与父类中同名的变量,那么子类中会隐藏父类的变量。但不是完全覆盖。在子类初始化的时候依然会为父类变量分配内存空间。通过父类中public属性的方法仍然可以访问父类的对应属性。

如下示例:水果父类中名字 苹果类中名字重复

package com.zmd.study.exten;

public class Fruit {
    /**
     * 水果的重量属性
     */
    private double weight ;

    /**
     * 名字
     */
    private String name = "水果";

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
    public void showInfo(){
        //被子类重写的方法
        System.out.println("我是"+ name +",我的重量是:" + weight );
    }
}

苹果类

package com.zmd.study.exten;

import java.sql.SQLOutput;

/**
 * @ClassName Apple
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/3/28.
 */
public class Apple extends Fruit{
    public String name = "苹果";
    public String color ;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public void showInfo(){
        //调用父类中的方法用super
        super.showInfo();
        System.out.println("我是"+ name +",我的重量是:" + this.getWeight());
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        apple.setWeight(0.2);
        apple.showInfo();
    }
}

输出:

我是水果,我的重量是:0.2
我是苹果,我的重量是:0.2

父类中含有构造方法

父类中只有一个有参构造。则子类构造方法必须给父类构造方法参数传值:

  即有参构造方法会覆盖无参构造方法,当不存在无参构造方法不存在的时候,java自动会运行一个空的无参构造方法。

如果子类构造方法不想给父类调用父类有参构造:父类必须含有无参构造方法。

语法:
    public 类名([参数列表]){
        完成对子类成员变量赋值;
        super(参数); //完成对父类构造方法赋值
    }

水果(父)类举例

package com.zmd.study.exten;

/**
 * @ClassName Fruit
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/3/28.
 */
public class Fruit {
    /**
     * 水果的重量属性
     */
    private double weight ;

    /**
     * 名字
     */
    private String name = "水果";

    /**
     * 父类无参构造方法
     */
    public Fruit() {
    }

    /**
     * 父类有参构造方法
     * @param weight
     * @param name
     */
    public Fruit(double weight, String name) {
        this.weight = weight;
        this.name = name;
    }
    public void showInfo(){
        //被子类重写的方法
        System.out.println("我是"+ name +",我的重量是:" + weight );
    }
}

苹果类~子类

package com.zmd.study.exten;

import java.sql.SQLOutput;

/**
 * @ClassName Apple
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/3/28.
 */
public class Apple extends Fruit{
    public String name = "苹果";
    public String color ;

    /**
     * 子类无参构造
     */
    public Apple() {
    }

    /**
     * 子类有参构造
     * @param weight
     * @param name
     */
    public Apple(int weight, String name) {
        super(weight,name);
    }
}

对比说明

 

 

 

实例化子类过程中发生了什么?

 1、子类名obj =  new 子类();

    2、执行了父类对应构造super()
     如果不手动执行super(参数),而子类构造方法中直接执行对父类的成员变量赋值,则默认会执行super()父类无参构造一次
    则:需注意,构造方法无参的无用也要写上避免出现错误

所有类的祖类(默认父类)都是Object

instanceof 判断前面的实例是不是后面类的实现

public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        System.out.println(apple instanceof Object);
}
/**
输出:true
*/

 

多态特性

Javad 引用变量有两个类型,一个是编译时类型,一个是运行时类型。

编译时类型由声明该变量时使用的类型决定。

运行时类型由实际赋给该变量的对象决定,如果编译时类型和运行时类型不一致,就可能出现所谓的“多态”

通俗理解:用父类声明变量,用子类来实例化   

语法:
    父类类名 引用名称 = new 子类类名();

    注意,引用名称.只能访问父类的实例属性和实例方法,如果子类重写了父类的方法,则优先访问子类的方法。

示例:动物类、 下属 猫类、狗类

package com.zmd.study.exten;

public class Animal {
    public void say(){
        System.out.println("本动物要叫了....");
    }
}
package com.zmd.study.exten;
public class Dog extends Animal{
    public void say(){
        System.out.println("小狗汪汪汪~~~!!!");
    }
}
package com.zmd.study.exten;
public class Cat extends Animal{
    public void say(){
        System.out.println("本小猫 喵喵喵~~~!!!");
    }
}

测试类

//import org.omg.Messaging.SYNC_WITH_TRANSPORT;

import com.zmd.study.exten.Animal;
import com.zmd.study.exten.Cat;
import com.zmd.study.exten.Dog;


public class Test {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        dog.say();
        cat.say();
}
/**
小狗汪汪汪~~~!!!
本小猫 喵喵喵~~~!!!
*/

使用子类特有的方法报错:比如小狗比动物多了生气的方法

package com.zmd.study.exten;

public class Dog extends Animal{
    public void say(){
        System.out.println("小狗汪汪汪~~~!!!");
    }
    public void angry(){
        System.out.println("小狗生气了~要咬人");
    }
}

测试

import com.zmd.study.exten.Animal;
import com.zmd.study.exten.Cat;
import com.zmd.study.exten.Dog;

public class Test {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.angry();//这里直接报语法错误:找不到符号,因为父类中没有
}

强制类型转换

语法:子类类型 引用名称 = (子类类型) 父类对象

注意:需要保证当前运行时的对象,一定是我们要转换对象的实例或者子类的实例。

import com.zmd.study.exten.Animal;
import com.zmd.study.exten.Cat;
import com.zmd.study.exten.Dog;

public class Test {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Dog dog1 = (Dog)dog;
        dog1.angry();
}
/**
小狗生气了~要咬人
*/

instanceOf 关键字

判断实例是不是后面类或者子类实例化的一个对象

语法:<引用类型的变量> instanceOf  <类>

返回布尔值true/false

示例

        System.out.println(dog instanceof Animal);
        System.out.println(dog instanceof Cat);
/**
true
false
*/

 

posted on 2021-03-28 11:16  zhangmingda  阅读(280)  评论(0编辑  收藏  举报

导航