第七节 继承、抽象类和接口

继承的概述

代码示例:

class Person{                               //  父类
    String name;
    int age;
    char sex;
    String idcard;

}

class Students extends Person{             //子类 继承 父类的属性

    public void study(){

        System.out.println("好好学习");
}

}

class Worker extends Person{             //子类 继承 父类的属性
/* 我们通过继承的方式,可以省略掉Worker的属性

*/ public void work(){ System.out.println("我有一份好工作");   } } 

继承:

1、提高了代码的复用性。

2、让类与类之间产生了关系。有了这个关系才有了多态的特性。

注意:
不要为了获取其他类的功能而继承,必须是类与类之间所属关系才可以继承。 所属关系:谁包含谁

java语言中只支持单继承,不支持多继承。因为多继承容易产生隐患:当父类中定义了相同功能,功能实现不同,我们在调用的时候不清楚调用的是哪个功能。多继承经过改良了之后被称之为多实现
但是java支持多层继承。也就是一个继承体系。
如何使用一个继承体系中的功能?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性的内容,因为了解共性功能,就可以了解该功能的基本功能。那么这个体系已经可以基本使用了,
在具体调用时,要创建最子类的对象,因为有可能父类不能创建对象;创建子类对象可以使用更多的功能,包括基本的也包括特有的。--->查阅父类功能,创建子类对象使用功能

子父类中变量的特点

子父类出现后,类成员的特点:

类中成员:

1、变量

如果子类中出线非私有的同名成员变量,用this;
子类要访问父类中的同名变量,用super;
super的使用和this的使用几乎一致,this代表本类对象的引用,super代表父类对象的引用。

2、函数

3、构造函数

继承的特点

函数重载和覆盖

重载(overload)

对于类的方法(包括从父类中继承的方法),方法名相同,参数列表不同的方法之间就构成了重载关系。这里有两个问题需要注意:
(1)什么叫参数列表?参数列表又叫参数签名,指三样东西:参数的类型,参数的个数,参数的顺序。这三者只要有一个不同就叫做参数列表不同。
(2)重载关系只能发生在同一个类中吗?非也。这时候你要深刻理解继承,要知道一个子类所拥有的成员除了自己显式写出来的以外,还有父类遗传下来的。所以子类中的某个方法和父类中继承下来的方法也可以发生重载的关系。
大家在使用的时候要紧扣定义,看方法之间是否是重载关系,不用管方法的修饰符和返回类型以及抛出的异常,只看方法名和参数列表。而且要记住,构造器也可以重载。

覆盖 (override)

也叫重写,就是在当父类中的某些方法不能满足要求时,子类中改写父类的方法。
当父类中的方法被覆盖了后,除非用super关键字,否则就无法再调用父类中的方法了。

发生覆盖的条件:
1、“三同一不低” 子类和父类的方法名称,参数列表,返回类型必须完全相同,而且子类方法的访问修饰符的权限不能比父类低。
2、子类方法不能抛出比父类方法更多的异常。即子类方法所抛出的异常必须和父类方法所抛出的异常一致,或者是其子类,或者什么也不抛出;
3、被覆盖的方法不能是final类型的。因为final修饰的方法是无法覆盖的。
4、被覆盖的方法不能为private。否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
5、被覆盖的方法不能为static。所以如果父类中的方法为静态的,而子类中的方法不是静态的,但是两个方法除了这一点外其他都满足覆盖条件,那么会发生编译错误。反之亦然。即使父类和子类中的方法都是静态的,并且满足覆盖条件,但是仍然不会发生覆盖,因为静态方法是在编译的时候把静态方法和类的引用类型进行匹配。

java修饰符

子类的实例化过程

子父类中的构造函数

在对子类对象进行初始化时,父类的构造函数也会运行,因为子类的构造函数第一行默认有一条隐士语句super();super()会访问父类中的空的构造函数,而且子类中所有的构造函数默认第一行都是super().

代码示例:

class Fu{
    Fu(){
    System.out.println("Fu无参")

    }
    FU(int age){
    System.out.println("Fu有参")
    }
}

class Zi extends Fu{

    Zi(){
    //第一行隐士 super();
    System.out.println("子无参")

    }   

    Zi(int age){
    System.out.println("子有参")   

    }

}

class Test{
    public static void main(String[] args) {
        Zi zi = new Zi();
        Zi zi1 = new Zi(3);
        //控制台输出结果:Fu无参;子无参;Fu无参;子有参;

    }

}

为什么子类一定要访问父类中的构造函数?

因为父类中public的子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类的构造函数。
如果访问父类中指定的构造函数,可以通过手动定义super()语句的方式来指定。
注意:
super()语句一定定义在子类构造函数的第一行。

final关键字(最终)

final 可以修饰类,方法,变量(为了避免被继承,被子类复写)
final 修饰的类不可以被继承
final 修饰的方法不可以被覆盖
final 修饰的变量是一个常量,只能被赋值一次,既可以修饰成员变量,也可以修饰局部变量
当在描述事物时,一些数据的出现值时固定的,不需要改变的。所以加上final修饰。
内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。

class Demo{
 final int a = 5; //表示x一只都是5,不能被改变。
 public static void main(String[] args) {
            final int y = 6;
             y = 8;
            System.out.println(y);// 我们家上final表示最终的,不能改变。

    }

}

?

抽象类

当多个类中出现了相同功能,但是功能主体不同,也可以进行向上抽取,此时只抽取功能定义,而不抽取功能主体。关键字:abstract
特点:
1、抽象方法一定定义在抽象类中;
2、抽象方法和抽象类都要被关键字abstract 修饰;
3、抽象类不能new创建对象,因为调用抽象方法没有意义;
4、抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。如果子类只覆盖了部分了抽象方法,该子类也还是抽象类。
代码示例:

abstract class Fu{
/*  void study(){
   System.out.println("FU");
  }    因为没有意义,所以使用抽象方法 */

  abstract void study();

}

class Zi extends Fu{
     void study(){
        System.out.println("Zi");
     }

}

class Zi1 extends Fu{
     void study(){
        System.out.println("Zi1");
     }

}

抽象类和一般的类没有太大的不同。只不过在抽象类里面我们有一些功能,这些功能不确定具体怎么实现,所以不需要明确的出现,但是所以不需要定义主体,通过我们的抽象方法来实现。
抽象类比一般类多了抽象方法;(抽象只能定义类或方法,不能定义变量)抽象类不能实例化;

练习:有员工类,具有姓名,工号,工资三个属性,经理也有三个属性,但是经理还有奖金的属性,请使用继承的思想设计出员工类和经理类,要求类中提供必要的方法进行属性访问。

模版设计模式

在定义功能时,功能的一部分是确定的 ,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将不确定的部分提供出去,由子类去完成。
需求:获取程序开始的时间,运行的时间,结束的时间

abstract class GetTime{
    public final void getTime(){
    long start = System.currentTimeMillis();//当前时间与协调世界时间1970年1月1日午夜至今的时间差(毫秒为单位测量)
        run();
    long end = System.currentTimeMillis();

    System.out.println("运行毫秒:"+(end - start));

    }
        public abstract void run();

}

class SubTime extends GetTime{

    public void run(){
        for(int i = 0 ;i < 1000;i++){
            System.out.println(i);
        }
    }

}

public Test{

    public static void main(String[] args){

        /*GetTime get = new  GetTime(); //此类为抽象类,不能new对象。*/
                    SubTime get = new SubTime();
                        get.getTime();
    }

}

接口

是什么?

例如我定义了一个接口,但是我在继承这个接口的类中还要写接口的实现方法,那我不如直接就在这个类中写实现方法岂不是更便捷,还省去了定义接口?

接口就是个招牌。

比如说你今年放假出去杭州旅游,玩了一上午,你也有点饿了,突然看到前面有个店子,上面挂着KFC,然后你就知道今天中饭有着落了。

KFC就是接口,我们看到了这个接口,就知道这个店会卖炸鸡腿(实现接口)。

那么为神马我们要去定义一个接口涅,这个店可以直接卖炸鸡腿啊(直接写实现方法),是的,这个店可以直接卖炸鸡腿,但没有挂KFC的招牌,我们就不能直接简单粗暴的冲进去叫服务员给两个炸鸡腿了。

要么,我们就要进去问,你这里卖不卖炸鸡腿啊,卖不卖汉堡啊,卖不卖圣代啊(这就是反射)。很显然,这样一家家的问实在是非常麻烦(反射性能很差)。
要么,我们就要记住,中山路108号卖炸鸡,黄山路45号卖炸鸡(硬编码),很显然这样我们要记住的很多很多东西(代码量剧增),而且,如果有新的店卖炸鸡腿,我们也不可能知道(不利于扩展)。

可以认为是一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。关键字:interface
接口定义时,格式特点:
1、接口中常见定义:常量,抽象方法;
2、接口中的成员都有固定修饰符。
常量:public、static、final
方法:public abstract
总结:接口中的成员都是public 的;接口时不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。

示例:

interface Inter{
    public static final int NUM = 6;
    public abstract void show();

}

class Test implements Inter{

    public void show(){
    }
}

public Demo{
    public static void main(String[] args){
        Test t = new Test();
        System.out.println(t.NUM);
        System.out.println(Test.NUM);
        System.out.println(Intert.NUM);

    }

}

接口可以被类多实现

示例:

interface Inter1{

}
interface Inter2{

}
class Test implements Inter1,Inter2{

}

接口的特点:
接口是对外暴露的原则;
接口是程序的功能扩展;
接口可以用来多实现;
类与接口至简是实现关系,而且类可以继承一个类的同时实现多个接口;
接口与接口之间可以有继承关系;

时间: 2024-08-09 06:33:24

第七节 继承、抽象类和接口的相关文章

java中抽象类和接口的用法和区别

一.抽象类 1.抽象类 包含一个抽象方法的类就是抽象类 2.抽象方法 声明而未被实现的方法,抽象方法必须使用abstract关键词字声明 public abstract class People { //关键词abstract,声明该类为抽象类 public int age; public void Num() { } public abstract Name(); //声明该方法为抽象方法 } 3.抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中的所有抽象方法 4.抽象类不能被直接实例

Java基础-抽象类和接口

抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 抽象定义: 抽象就是从多个事物中将共性的,本质的内容抽取出来.     例如:狼和狗共性都是犬科,犬科就是抽象出来的概念. 抽象类: Java中可以定义没有方法体的方法,该方法的具体实现由子类完 成,该方法称为抽象方法,包含抽象方法的类就是抽象类. 抽象方法的由来: 多个对象都具备相同的功能,但是功能具体内容有所不

面向对象 多态、抽象类和接口

今天,我主要学习了多态.抽象类和接口的部分内容. 在实际的操作中,同样都是继承了同一个父类,但是父类中的方法并不适用任何一个子类,那么在这就需要子类重新编写这个方法的主体. 在重写成员方法时,需要父类同意子类可以重新编写自己的方法:virtual -  虚方法:子类只能重写父类允许重写的方法,只能重写虚方法:override - 重写覆盖虚方法. 基类与派生类是相对的,所有的类都可以当做父类,都可以有虚方法. 抽象类:abstract 抽象类就是为了被继承而出现的.普通的类中所有的方法都变成虚方

抽象方法,抽象类,接口

抽象类:具有抽象方法的类就是抽象类 抽象方法:没有方法体的方法就是抽象方法 作用:主要协同工作,制定标准 特征: 抽象方法就是没有方法体的方法, 方法体就相当于函数体,抽想方法前,必须使用abstract 关键字,且方法后不能够写{},但是要写结束符; 如果类中有抽象方法,那么这个类的前面也需要 abstract关键字修饰 抽象类中可以有非抽象方法 抽象类可以参数,要实现该抽象方法,必须传入同样参数 不能直接实例化,必须由其他的类继承并且完全实现出所有的抽象方法,才可以使用,抽像类主要是给其他类

黑马程序员——面向对象(一)概述、类与对象、继承、抽象类、接口、多态、内部类

一.面向对象概述 1.面向对象:是一个很抽象的概念,它相对面向过程而言,是一种程序设计的思想. 2.面向对象的特点: * 符合人们思考习惯的思想 * 可以将复杂的事情简单化 * 将程序员从执行者转换成了指挥者 * 完成需求时:只需要寻找具备所需功能的对象或者创建所需功能的对象即可,简化开发效率并提高对象的复用性. 3.面向对象的三个特征:封装(Encapsulation).继承(Inheritance).多态(Polymorphism). 二.类与对象 (一)类与对象之间的关系 1.类的定义:类

Java入门系列之类继承、抽象类、接口(五)

前言 C#和Java关于类.抽象类.接口使用方式基本相似,只是对应关键字使用不同罢了,本节呢,我们只是对照C#和Java中关于这三个概念在具体使用时,看看有哪些不一样的地方. 类继承 C#和Java在定义类方式上是一致的,这点没有什么太多要讲解的,我们直接进入到类继承上,在Java中实现继承通过extends关键字,而在C#中则是以冒号(:)来继承,非常优雅而简洁,Java如下: class Animal{} class Tiger extends Animal{} 在C#中如下: class

一个接口能否继承另一个接口?一个抽象类能否实现一个接口?

都可以: 一.一个接口能否继承另一个接口? 接口继承接口  本质就是一个抽象类继承另一个抽象类(它们都没写方法的实例).当一个类继承了一个抽象类,它必须要重写父类 抽象类中的抽象方法,如果不去重写父类抽象方法的实例,那么这个类也是抽象类(这个抽象子类,直到重写这个抽象方法的实例为止, 才能摆脱抽象的命运).其实我们想想,一个类去实现一个接口也不就是一个实体子类把一个抽象的所以抽象方法实例化(重写了 抽象父类 中全部抽象方法),当然抽象类和接口还是有区别的.我上上篇就写到了抽象类和接口的区别,有兴

面向对象二 — — 继承、抽象类、接口

一.继承 extends 继承的特点:Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类 1.参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载. 2.返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载. 3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private) 4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常. 用supe

[原创]抽象类实现接口,子类继承抽象类,这三者之间的关系?

①一个类实现一个接口,那么这个类必须实现该接口中的所有方法,因为接口中的方法默认都是 public,abstract类型的,所以实现接口的类都必须重写该接口中的所有方法,比如: interface A { boolean add(); boolean offer1(); boolean offer2(); } public class Test01 implements A{//必须实现A接口中的所有方法 @Override public boolean add() { return false