java面向对象基础(四):抽象类和接口

*/

.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}

.hljs-comment,
.hljs-template_comment,
.diff .hljs-header,
.hljs-javadoc {
color: #998;
font-style: italic;
}

.hljs-keyword,
.css .rule .hljs-keyword,
.hljs-winutils,
.javascript .hljs-title,
.nginx .hljs-title,
.hljs-subst,
.hljs-request,
.hljs-status {
color: #333;
font-weight: bold;
}

.hljs-number,
.hljs-hexcolor,
.ruby .hljs-constant {
color: #099;
}

.hljs-string,
.hljs-tag .hljs-value,
.hljs-phpdoc,
.tex .hljs-formula {
color: #d14;
}

.hljs-title,
.hljs-id,
.coffeescript .hljs-params,
.scss .hljs-preprocessor {
color: #900;
font-weight: bold;
}

.javascript .hljs-title,
.lisp .hljs-title,
.clojure .hljs-title,
.hljs-subst {
font-weight: normal;
}

.hljs-class .hljs-title,
.haskell .hljs-type,
.vhdl .hljs-literal,
.tex .hljs-command {
color: #458;
font-weight: bold;
}

.hljs-tag,
.hljs-tag .hljs-title,
.hljs-rules .hljs-property,
.django .hljs-tag .hljs-keyword {
color: #000080;
font-weight: normal;
}

.hljs-attribute,
.hljs-variable,
.lisp .hljs-body {
color: #008080;
}

.hljs-regexp {
color: #009926;
}

.hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.lisp .hljs-keyword,
.tex .hljs-special,
.hljs-prompt {
color: #990073;
}

.hljs-built_in,
.lisp .hljs-title,
.clojure .hljs-built_in {
color: #0086b3;
}

.hljs-preprocessor,
.hljs-pragma,
.hljs-pi,
.hljs-doctype,
.hljs-shebang,
.hljs-cdata {
color: #999;
font-weight: bold;
}

.hljs-deletion {
background: #fdd;
}

.hljs-addition {
background: #dfd;
}

.diff .hljs-change {
background: #0086b3;
}

.hljs-chunk {
color: #aaa;
}

#container {
padding: 15px;
}
pre {
border: 1px solid #ccc;
border-radius: 4px;
display: block;
background-color: #f8f8f8;
}
pre code {
white-space: pre-wrap;
}
.hljs,
code {
font-family: Monaco, Menlo, Consolas, ‘Courier New‘, monospace;
}
:not(pre) > code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
white-space: nowrap;
border-radius: 4px;
}
-->

抽象类(abstract)

  1. 使用abstract关键字来修饰的类是抽象类。使用abstract修饰方法时这个方法称为抽象方法。
  2. 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
  3. 抽象类不能被实例化,即不能new该类对象。因为抽象类是比较抽象的类,是残缺不全的类。
  4. 抽象方法只需定义它的结构,不需写方法体。因为抽象方法最终都要被子类重写,即使定义抽象方法也是多余的。
  5. 抽象类中并非一定要包含抽象方法,也并非不能包含普通方法。

以下面多态的示例来说明:

class Animal {
  private String name;
  Animal(String name) {this.name = name;}

  public void sing(){System.out.println("animal sing...");} //这是多余的方法
}

class Cat extends Animal {
  private String eyeColor;
  Cat(String n,String c) {super(n); eyeColor = c;}

  public void sing() {System.out.println("cat sing...");}
}

class Dog extends Animal {
    private String furColor;
    Dog(String n,String c) {super(n); furColor = c;}

    public void sing() {System.out.println("dog sing...");}
}

class Lady {
    private String name;
    private Animal pet;
    Lady(String name,Animal pet) {this.name = name; this.pet = pet;}
    public void myPetSing(){pet.sing();}
}

public class DuoTai {
    public static void main(String args[]){
        Cat c = new Cat("catname","blue");
        Dog d = new Dog("dogname","black");
        Lady l1 = new Lady("l1",c);
        Lady l2 = new Lady("l2",d);
        l1.myPetSing();
        l2.myPetSing();
    }
}

父类Animal中的sing()方法迟早要被子类Cat、Dog重写,而且在多态实现下,Animal的sing()完全是多余的。因此,可以将Animal的sing()方法的方法体删掉。

class Animal {
  private String name;
  Animal(String name) {this.name = name;}

  public void sing() {}
}

更彻底一点,将sing()方法加上abstract关键字,这个方法变为抽象方法,抽象方法是不完整的方法,它必须被子类重写。抽象方法所在的类也必须加上abstract关键字变成抽象类。成了抽象类后这个类也是不完整的类,所以无法实例化new Animal

abstract class Animal {
  private String name;
  Animal(String name) {this.name = name;}

  public abstract void sing();
}

虽然Animal中的sing()用不上了,但它却必须要定义出来,因为它要被子类重写。另外,如果子类不想重写抽象方法,可以将这个子类也定义为抽象类,并让子子类去重写。

接口(interface)

接口定义的是一种具有某种能力的标准,通过接口实现的方式来体现如何具有该这些能力。说白了它就是能实现某些能力的标准。

例如定义一个USB接口的标准,各厂商如何去实现这个标准由各厂商自己去决定,但不管如何,各厂商实现的USB接口必须达到标准所要求具有的能力。

放在编程语言中来说,接口是一种特殊的抽象类,里面的方法必须全部是抽象方法且都是public的,里面的变量也必须都是"public static final"属性的。即使不写这些修饰关键字,默认也是这些属性,但如果写了,就绝对不能写错。

定义接口的方式是使用interface关键字替代class关键字。例如以下定义一个Singable接口,要求必须有喉咙,且能唱歌,能临时停止唱歌。

interface Singable {
    public static final boolean houlong = true;

    public void sing();
    public void tmpStop();
}

既然接口是一种抽象类,那么就可以被继承,且里面的方法必须要重写以体现各子类独有的能力。通常接口都被命名为"XXXable",因为接口一般体现的是具有某种能力。

继承接口这个特殊类的术语是"实现接口",使用implement关键字。某个类可以实现多个接口,也就是"多重继承"。不仅如此,实现接口的同时还可以实现extends继承其他类。有以下几种写法:

class A implement intf1 {}
class A implement intf1,intf2 {}
class A extends ParentClass implement intf1,intf2 {}

以下是一个示例,定义了Singable和Paintable两个接口,还定义了两个实现这两接口的类Student和Teacher,它们分别有各自的方法study()和teach()。

interface Singable {
    public void sing();
}

interface Paintable {
    public void paint();
}

class Student implements Singable {
    private String name;
    Student(String name) {this.name = name;}

    public void study() {System.out.println("Student studing...");}

    // overwrite methods
    public void sing() {System.out.println("Student singing...");}
}

class Teacher implements Singable,Paintable {
    private String name;
    Teacher(String name) {this.name = name;}

    public void teach() {System.out.println("Teacher teaching...");}

    // overwrite methods
    public void sing() {System.out.println("Teacher singing...");}
    public void paint() {System.out.println("Teacher painting...");}
}

public class Interface {
    public static void main(String[] args) {
        Singable s1 = new Student("Malongshuai");
        s1.sing();
        //s1.study();   //return error! because s1 upcasting from Student to Singable
        Student s = (Student)s1;
        s.study();  //return true

        Singable t1 = new Teacher("Gaoxiaofang");
        t1.sing();
        //t1.paint(); //return error! t1 upcasting from Teacher to Singable,not Paintable
        Paintable t = (Paintable)t1;
        t.paint();
    }
}

上面的示例中,Student类实现了Singable接口,所以它重写了sing(),Teacher类实现了Singable接口和Paintable接口,所以它重写了sing()和paint()。

需要注意的点在于接口和实现接口的类之间具有多态性。正如上面的Singable t1 = new Teacher("Gaoxiaofang");,此时t1虽然引用的是Teacher对象,但它能识别的数据只有Singable接口的成员sing(),而无法识别Teacher自身的方法teach()和Paintable接口的方法paint(),且因为子类Teacher重写了Singable中的sing(),所以多态性使得t1.sing()调用的是Teacher重写后的sing()。要访问paint(),需要将t1转型为Paintable类型或者Teacher类型,要访问teach(),就必须转型为Teacher类型。

注:若您觉得这篇文章还不错请点击右下角推荐,您的支持能激发作者更大的写作热情,非常感谢!

原文地址:https://www.cnblogs.com/f-ck-need-u/p/8127993.html

时间: 2024-10-08 03:21:35

java面向对象基础(四):抽象类和接口的相关文章

java面向对象编程(八)--抽象类、接口

1.抽象类 1.1抽象类概念 当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract来修饰该类[抽象类]. //抽象类的必要性[Demo124.java] public class Demo124 { public static void main(String[] args) { //Animal an=new Animal();抽象类不允许实例化 Animal an=new Cat(); an.cry(); an=new Dog(); an.cr

面向对象基础之抽象类与接口 下

在上篇博文中我们一起了解了抽象类,那么什么是接口呢?下面给大家简单介绍一下: 所谓接口,就是把隐式公共方法和属性组合起来,以封装特定功能的一个集合.一旦类实现了接口,类就可以支持接口所指定的所有属性和成员.声明接口在语法上与声明抽象类完全相同,但不允许提供接口中任何成员的执行方式,因此接口不能实例化,不能有构造方法和字段,不能有修饰符,如public等.在实现接口的类中必须实现接口中的所有方法和属性. 一个接口可以支持多个接口,多个类也可以支持相同的接口.需要注意的是,接口用interface关

面向对象基础之抽象类与接口 上

在两年前学习C++的时候,知道抽象类这么一个概念,当时并不是很理解,如今在学习C#和设计模式的时候,再一次碰到了这个含糊不清的东西,同时又在C#中学习到了接口技术,接口也早有耳闻,但是当时理解的接口就是一个或者一组能够操作类中数据的函数或者方法.虽然老师举过很多例子,比如电视机这个事物,它对外的接口就是遥控器,遥控器里好多的按钮,按钮的下面就是各种各样的命令或者称之为方法. 当抽象类遇到接口的时候,顿时蒙圈了,这两个概念的确是让人很难区别,那么我今天就来总结一下抽象类和接口到底有哪些区别和联系,

java基础之抽象类与接口的区别

在学习java的过程中,或者是在找工作笔试或面试的时候,如果你是java岗位,那么抽象类与接口的区别无疑是一个大热点,是各大公司都想要考的一个小知识点,下面是我为了9月份秋招自己总结的,若有不对的地方,欢迎指正. 此处,借鉴了http://www.cnblogs.com/dolphin0520/p/3811437.html,写的很不错. 一.抽象类 使用了abstract关键字所修饰的类叫做抽象类.抽象类无法实例化,也就是说,不能new出来一个抽象类的对象(实例). 抽象方法:使用abstrac

【Java面向对象基础(三)】面向对象思想

[喵"的Android之路][基础篇(三)][Java面向对象基础]面向对象思想 1 面向对象的WWH 1.1 What--什么是面向对象 首先,要理解“对象”.在Thinking in Java中提到“Everything is an object”,即万物皆对象.这里的“对象”指的是任何实体或者任何可以当作实体看待的“虚幻的事物”.比如现实中的人(男人.女人.老人.小孩而...).动物(大象.狮子.猴子...).桌子.凳子.汽车.ATM机等等,也可以使看不见摸不着的空气(氧气.二氧化碳.氮气

Java语言中的----抽象类、接口

day12  Java语言中的抽象类与接口 一.抽象类和接口概述; 在昨天我们学习了Java的继承功能,这个是一个核心知识点,今天我们再继承的基础之上学习一下抽象类和接口这两个知识.什么是抽象类?如何定义一个抽象类?如何使用一个抽象类?这些都是我们需要掌握的. 同时我们还要知道如何来定义一个接口,在开发中定义接口来实现相关的功能是一个很重要的功能.如何来实现接口中的抽象方法,这些在这一节都会说到. 二.抽象类和接口 1.抽象类: 什么是抽象类?包含抽象方法的类就叫做抽象类 .使用abstract

【Java面向对象基础(一)】数据类型与运算符

[喵"的Android之路][基础篇(一)][Java面向对象基础]数据类型与运算符 1.数据类型介绍 在Java中,数据类型分为两种:基本数据类型和引用类型. 基本数据类型共8种,见下表: 基本数据类型 字节数 二进制位数 最小值 最大值 默认值 byte 1 8-bit -2^7 +2^7 - 1 0 short 2 16-bit -2^15 +2^15 - 1 0 int 4 32-bit -2^31 +2^31 - 1 0 long 8 64-bit -2^63 +2^63 - 1 0

【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder

[喵"的Android之路][基础篇(二)][Java面向对象基础]细说String.StringBuffer和StringBuilder 1.String String是Java中的一个final类,主要用于字符串的处理. 1.1 不可变性 String内的字符串是不可变的,每一次修改都会重新生成一个新的String对象实例. 例: 1 // 在堆中会创建一个"Hello"字符串实例,把地址赋给对象a 2 String a = new String("Hello&

黑马程序员——Java基础——面向对象——继承、抽象类、接口、多态、包、内部类、异常等

第一讲 继承 1.继承: 当多个类拥有相同的功能时,那么这些类不需要每个都写这些相同的功能,只需要把相同功能抽到 一个单独的类中,继承这个类就能获得这些相同的功能: (1)继承的体系结构:就是对要描述的事物进行不断的向上抽取,就出现了体系结构. 要了解这个体系结构中最共性的内容,就看最顶层的类. 要使用这个体系的功能,就用最底层的类创建对象 (2)好处: A.提高代码复用性: B.继承的出现,让类与类之间产生关系,为多态的前提 (3)特点: A.只能单继承(准确的说是java对多继承进行优化,避