《JAVA:从入门到精通》part 11

十三、抽象类

  • 在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承和多态处理。回想继承和多态原理,继承树中越是在上方的类越抽象,例如鸽子类继承鸟类、鸟类继承动物类等等。在多态机制中,并不需要将父类初始化对象,我们需要的只是子类对象,所以在JAVA语言中设置抽象类不可以实例化对象,因为图形类不能抽象出任何一种具体图形,但是他的子类可以。

  • 抽象类的语法如下:

    public abstract class Test
    {
          abstract void testAbstract();             //定义抽象方法
    }
    
  • 其中,abstract是定义抽象类的关键字。使用abstract关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承之外没有任何意义。

  • 反过来说,如果声明一个抽象的方法,就必须将承载这个抽象方法的类定义为抽象类,不可能在非抽象类中获取抽象方法。换句话说,只要类中有一个抽象方法,此类就被标记为抽象类。

抽象类案例:

chouxiang1.java

package lianxi2;
public class chouxiang1
{
    public static void main(String[] args)
    {
        color c1=new red();
        color c2=new blue();
        c1.show();
        c2.show();
    }
}

color.java

package lianxi2;

public abstract class color
{
    public void show()
    {

    }
}
class red extends color
{
    public void show()
    {
        System.out.println("我是红色");
    }
}
class blue extends color
{
    public void show()
    {
        System.out.println("我是蓝色");
    }
}

运行结果:

  • 可以看到该抽象父类中的方法没有任何意义,只是给子类继承用的。子类继承父类的方法后可以重新改写。在chouxiang1.java中如果加上语句
    color c3=new color();
    则编译会出错,因为抽象类不能被实例化。

抽象方法案例:

chouxiang2.java

package lianxi2;

public class chouxiang2
{
    public static void main(String[] args)
    {
        teacher tony=new mathteacher();
        teacher john=new englishteacher();
        tony.teaching();
        john.teaching();
    }
}

teacher.java

package lianxi2;

public abstract class teacher
{
    public abstract void teaching();
}
class mathteacher extends teacher
{
    public void teaching()
    {
        System.out.println("这节课讲三角函数");
    }
}
class englishteacher extends teacher
{
    public void teaching()
    {
        System.out.println("open the book");
    }
}

运行结果:

如何使用抽象方法案例:

chouxiang3.java

package lianxi2;

public class chouxiang3
{
    public static void main(String[] args)
    {
        seagull lina=new seagull("白色");
        lina.move();
        lina.eat();
        lina.growferther();
        lina.reproduce();
        System.out.println();
        chicken xiaoji=new chicken("黄色");
        xiaoji.move();
        xiaoji.eat();
        xiaoji.growferther();
        xiaoji.reproduce();
    }
}

animal.java

package lianxi2;

public abstract class animal
{
    public animal()
    {
        System.out.println("创建了一个动物类");
    }
    public abstract void eat();
    abstract public void reproduce();
}

bird.java

package lianxi2;

public abstract class bird extends animal
{
    String ferther;
    public bird(String ferther)
    {
        System.out.println("创建了一个鸟类");
        this.ferther=ferther;
    }
    public void growferther()
    {
        System.out.println("长满"+ferther+"羽毛");
    }
    abstract public void move();
    public void reproduce()
    {
        System.out.println("下蛋");
    }
}

seagull.java

package lianxi2;

public class seagull extends bird
{
    public seagull(String ferther)
    {
        super(ferther);
        System.out.println("我是一只海鸥");
    }
    public void move()
    {
        System.out.println("海鸥飞翔");
    }
    public void eat()
    {
        System.out.println("海鸥吃鱼");
    }
}

chicken.java

package lianxi2;

public class chicken extends bird
{
    public chicken(String ferther)
    {
        super(ferther);
        System.out.println("我是一只小鸡");
    }
    public void move()
    {
        System.out.println("小鸡快跑");
    }
    public void eat()
    {
        System.out.println("小鸡啄米");
    }
}

运行结果:

  • 可以看到该程序是一个三层结构,animal和bird是抽象类,因为动物和鸟都有很多种,无法具体到某个物种,seagull和chicken不是抽象类,为具体的某个物种。另外有三个抽象方法:move()、eat()、reproduce()。

十四、接口

  • 接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。

  • 如图可以看到这是通常的继承关系,子类继承父类的所有方法。但是如果三角形类不需要void draw()这个方法,那只能删除父类(图形类)的void draw()方法,但是一旦删除父类的这个方法后,其他需要该方法的子类也就无法继承这个方法了,这就造成了功能缺失。

  • 所以就引入了接口这个概念,让需要void draw()这个方法的子类继承接口中的这个方法就行。

  • 接口使用interface关键字进行定义,其语法如下:

    public interface drawTest
    
    {
            void draw();
    }
    
  • 需要注意的是,在接口中,方法必须被定义为public或者abstract形式,其他修饰权限不能被JAVA编译器认可。或者说,即使不将该方法声明为public形式,它也是public。

  • 在接口中定义的任何字段都自动是static和final的。

多态与接口结合的案例:

package lianxi2;
interface drawTest { // 定义接口
    public void draw(); // 定义方法
}

// 定义平行四边形类,该类继承了四边形类,并实现了drawTest接口
class ParallelogramgleUseInterface extends QuadrangleUseInterface
        implements drawTest {
    public void draw() { // 由于该类实现了接口,所以需要覆盖draw()方法
        System.out.println("平行四边形.draw()");
    }

    void doAnyThing() { // 覆盖父类方法
        // SomeSentence
    }
}

class SquareUseInterface extends QuadrangleUseInterface implements
        drawTest {
    public void draw() {
        System.out.println("正方形.draw()");
    }

    void doAnyThing() {
        // SomeSentence
    }
}

class AnyThingUseInterface extends QuadrangleUseInterface {
    void doAnyThing() {

    }
}

public class QuadrangleUseInterface { // 定义四边形类
    public void doAnyTthing() {
        // SomeSentence
    }

    public static void main(String[] args) {
        drawTest[] d = { // 接口也可以进行向上转型操作
                new SquareUseInterface(), new ParallelogramgleUseInterface() };
        for (int i = 0; i < d.length; i++) {
            d[i].draw(); // 调用draw()方法
        }
    }
}

运行结果:

  • 在这个实例中,正方形类与平行四边形类分别实现了drawTest接口并继承了四边形类,所以需要覆盖接口中的方法。在调用draw()方法时,首先将平行四边形类对象与正方形类对象向上转型为drawTest接口形式。然后使用d[i]数组中的每一个对象调用draw(),由于向上转型,所以d[i]数组中的每一个对象分别代表正方形类对象和平行四边形类对象,最后结果分别调用正方形类和平行四边形类中覆盖的draw()方法。

接口与继承

  • JAVA中不允许出现多重继承,但是使用接口可以实现多重继承。一个类可以同时实现多个接口,因此可以将所有需要继承的接口放置在implements关键字后并用逗号隔开。但是这可能会在一个类中产生庞大的代码量,因为要继承一个接口时需要实现接口中所有的方法。

  • 多重继承的语法如下:

    class 类名 implements 接口1,接口2,···接口n
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容

  • 本文出自 Eddy Wiki ,转载请注明出处:http://eddy.wiki/interview-java.h...
    eddy_wiki阅读 1,206评论 0 5
  • java继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。 继承就是子类继...
    863cda997e42阅读 670评论 0 1
  • 整理来自互联网 1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具...
    Ncompass阅读 1,538评论 0 6
  • 一:java概述: 1,JDK:Java Development Kit,java的开发和运行环境,java的开发...
    慕容小伟阅读 1,789评论 0 10
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,653评论 0 11