面向对象--继承 demo(一)

简介: 面向对象--继承 demo(一)

继承


继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。


继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。


继承是面向对象最显著的一个特征

继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并扩展新的能力.


Java继承是会用已存在的类的定义作为基础建立新类的技术

新类的定义可以增加新的数据或者新的功能,也可以使用父类的功能,但不能选择性的继承父类(超类/基类)

这种继承使得复用以前的代码非常容易,能够大大的缩短开发的周期,降低开发费用.


继承有什么用?

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。


被继承的类叫父类,继承的类叫子类,比如类A继承类B,则B为父类,A为子类


继承的关键字为extends

语法:
class A extends B{
}


类的继承格式:

class 父类 { }
class 子类 extends 父类 { }


继承的类型:需要注意的是 Java 不支持多继承,但支持多重继承。


继承的好处:


(1)提高类代码的复用性


(2)提高了代码的维护性


(3)使得类和类产生了关系,是多态的前提(它也是继承的一个弊端,类的耦合性提高了)


继承的特性


子类拥有父类非 private 的属性、方法。


子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。


子类可以用自己的方式实现父类的方法,即重写父类方法。


Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。


继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。


提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。


特点

使用extends关键字来表示继承关系

相当于子类把父类的功能复制了一份

Java只支持单继承

继承可以传递(爷爷/儿子/孙子这样的关系)

父类的私有成员也会被继承,但由于是私有的不可见,所以子类不能使用父类的私有资源

继承多用于功能的修改,子类可以在拥有父类功能的同时,进行功能拓展

像是is a的关系


super

可以通过这个关键字使用父类的内容,Super代表的是父类的一个引用对象

注意:在构造方法里,出现的调用位置必须是第一行


补全构造方法


描述

有父类Base,内部定义了x、y属性。有子类Sub,继承自父类Base。子类新增了一个z属性,并且定义了calculate方法,在此方法内计算了父类和子类中x、y、z属性三者的乘积。请补全子类构造方法的初始化逻辑,使得该计算逻辑能够正确执行。

输入描述:

三个整数:x, y, z

输出描述:

三个整数的乘积:xyz


public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            int z = scanner.nextInt();
            Sub sub = new Sub(x, y, z);
            System.out.println(sub.calculate());
        }
    }
}
class Base {
    private int x;
    private int y;
    public Base(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
}
class Sub extends Base {
    private int z;
    public Sub(int x, int y, int z) {
        //write your code here
    }
    public int getZ() {
        return z;
    }
    public int calculate() {
        return super.getX() * super.getY() * this.getZ();
    }


答案解析:


我们的任务只是完善子类的构造方法。首先因为父类的成员变量都是private类型的,无法直接访问,因此赋初值只能通过super调用父类的构造方法,然后变量z是子类特有的,因此可以自己给自己赋值。


public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            int z = scanner.nextInt();
            Sub sub = new Sub(x, y, z);
            System.out.println(sub.calculate());
        }
    }
}
class Base {
    private int x;
    private int y;
    public Base(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
}
/**
 * 我们的任务只是完善子类的构造方法。首先因为父类的成员变量都是private类型的,无法直接访问,
 * 因此赋初值只能通过super调用父类的构造方法,然后变量z是子类特有的,因此可以自己给自己赋值。
 */
class Sub extends Base {
    private int z;
    public Sub(int x, int y, int z) { //子类构造方法
        super(x,y); //调用父类构造方法
        this.z=z;
        //write your code here
    }
    public int getZ() {
        return z;
    }
    public int calculate() {
        return super.getX() * super.getY() * this.getZ();
    }


运行结果是

1
2
3
6


重写计算逻辑


描述

在父类Base中定义了计算方法calculate(),该方法用于计算两个数的乘积(X*Y)。请在子类Sub中重写该方法,将计算逻辑由乘法改为除法(X/Y)。注意,当分母为0时输出“Error”。

输入描述:

两个整数

输出描述:

两个整数的商(int类型,不考虑小数情况)

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            Sub sub = new Sub(x, y);
            sub.calculate();
        }
    }
}
class Base {
    private int x;
    private int y;
    public Base(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public void calculate() {
        System.out.println(getX() * getY());
    }
}
class Sub extends Base {
    //write your code here......
}



解析答案


public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            System.out.println("除法");
            Sub sub = new Sub(x, y);
            sub.calculate();
            System.out.println("乘法");
           Base base= new Base(x, y);
           base.calculate();
        }
    }
}
class  Base {
    private int x;
    private int y;
    public Base(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public  void calculate() {
        System.out.println(getX() * getY());
    }
}
class Sub extends Base {
    public Sub(int x, int y) {
        super(x, y);
    }
    //write your code here......
   public void calculate() {
       if (getY() == 0) {
           System.out.println("Error");
       } else {
           System.out.println(getX() / getY());
       }
   }


结果为

5
10
除法
0
乘法
50


扩展: 理解extends与implements的区别


注意:若同时用到 extends 和 implements 的时候,extends 必须放在 implements 关键字之前。

class 子类名 extends 父类名 implenments 接口名
{...
}


Java只能单继承,接口为了弥补单继承的不足就出现了。


继承解决的是代码复用以及对象的关系,接口解决的是解耦.


1.在类的声明中,通过关键字extends来创建一个类的子类。一个类通过关键字implements声明自己使用一个或者多个接口。 extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法; implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用

2.extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,但是可以用接口 来实现,这样就要用到implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了

比如:EG

class A extends B implements C,D,E

implements是一个类实现一个接口用的关键字,他是用来实现接口中定义的抽象方法。比如:people是一个接口,他里面有say这个方法。

public interface people(){ public say();}

但是接口没有方法体。只能通过一个具体的类去实现其中的方法体。比如chinese这个类,就实现了people这个接口。

public class chinese implements people{ public say() {System.out.println("你好!");}}

接口实现的注意点:


a.实现一个接口就是要实现该接口的所有的方法(抽象类除外)。


b.接口中的方法都是抽象的。


c.多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口。


DEMO

这里有一个游戏,人猿泰山。 主角是一个单独的类,这里我们主要用怪物说明接口的用法: 怪物有很多种, 按地域分:有的在天上飞,有的在地上跑,有的在水里游 按攻击方式分:有的能近距离物理攻击,有的能远距离射击


假设游戏里需要这样的几 种怪——


野狗:地上移动,近距离攻击


黑熊:地上移动,近/远距离攻击


秃鹫:地上/天上移动,远距离攻击


食人鱼: 水中移动,近距离攻击


鳄鱼:地上/水中移动,近距离攻击


显然,如果我们将每一种怪物定义为一个类,那就不是面向对象的程序开 发了,我们应当使用接口:

interface OnEarth{//陆地接口
int earthSpeed;//陆地移动速度
void earthMove();//陆地移动方法
}
interface OnWater{//水中接口
int waterSpeed;//水中移动速度
void waterMove();//水中移动方法
}
interface OnAir{//空中接口
int airSpeed;//水中移动速度
void airMove();//水中移动方法
}
interface NearAttack{//近距离攻击接口
int nearAttackPower;//近距离攻击力
void nearAttack();//近距离攻击方法
}
interface FarAttack{//远距离攻击接口
int farAttackPower;//远距离攻击力
void farAttack();//远距离攻击方法
}
这样一来,根据需求,我们可以选择性的继承接口:
class Tyke implements OnEarth, NearAttack{//野狗类
void earthMove(){//实现继承的方法1
}
void nearAttack(){//实现继承的方法2
}
}
class BlackBear implements OnEarth, NearAttack, FarAttack{//黑熊类
void earthMove(){//实现继承的方法1
}
void nearAttack(){//实现继承的方法2
}
void farAttack(){//实现继承的方法3
}
}
class Vulture implements OnEarth, OnAir, FarAttack{//秃鹫类
void earthMove(){//实现继承的方法1
}
void airMove(){//实现继承的方法2
}
void farAttack(){//实现继承的方法3
}
}
class ManeatFish implements OnWater, NearAttack{//食人鱼类
void waterMove(){//实现继承的方法1
}
void nearAttack(){//实现继承的方法2
}
}
class Crocodile implements OnEarth, OnWater, NearAttack{//鳄鱼类
void earthMove(){//实现继承的方法1
}
void waterMove(){//实现继承的方法2
}
void nearAttack(){//实现继承的方法3
}
}
相关文章
|
3月前
|
编译器 C语言 C++
类和对象 | 类的引入、struct&class的区别、类的定义
类和对象 | 类的引入、struct&class的区别、类的定义
33 7
|
6月前
|
编译器 C语言 C++
【C++专栏】C++入门 | 类和对象 | 类的引入、struct&class的区别、类的定义
【C++专栏】C++入门 | 类和对象 | 类的引入、struct&class的区别、类的定义
38 0
|
6月前
|
编译器 C++
C++进阶--继承
C++进阶--继承
|
6月前
|
Java 编译器
JavaSE学习之--继承和多态(一)
JavaSE学习之--继承和多态
62 0
|
6月前
|
Java 编译器
JavaSE学习之--继承和多态(三)
JavaSE学习之--继承和多态(三)
62 0
|
6月前
|
Java
JavaSE学习之--继承和多态(二)
JavaSE学习之--继承和多态(二)
69 0
|
Java
面向对象--继承 demo(二)
面向对象--继承 demo(二)
115 1
|
存储 Java DataX
面向对象--封装 demo 练习
面向对象--封装 demo 练习
131 0
|
Java
接口和抽象类/方法学习 demo
接口和抽象类/方法学习 demo
70 0
|
JavaScript
js基于原型和class的面向对象-继承
js基于原型和class的面向对象-继承
76 0