浅谈Java抽象类以及接口

  Java几大特点当中继承算得上是一个就算是初学者也会使用的很频繁的一个属性了。而抽象类以及接口便是Java中最能体现继承特点的了

抽象类

抽象关键词与抽象方法

  在了解抽象类之前我们需要先了解一下抽象关键字 (abstract) 以及抽象方法。抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。具体的抽象方法的声明格式例如:

abstract void fun();

  一个方法要成为抽象方法,一定要使用抽象关键字(abstract)修饰。显而易见,如果一个类拥有抽象方法,那么这个类就可以称为抽象类,抽象类也必须使用抽象关键字修饰。虽然拥有抽象方法的类是抽象类,但是抽象类并不一定包含抽象方法,任何被抽象关键字修饰的类均可以被称为抽象类,即使它不包含任何抽象方法。抽象类中也并不是所有方法都是抽象方法,抽象类也可以包含有一般方法。由于不包含任何抽象方法的抽象类不具有实际意义,所以本文不对这种情况展开讨论。

抽象类的特征

  因为抽象类的目的就是用于继承所以抽象类会与普通类有些不一样的地方。

  抽象类包含的抽象方法权限修饰词必须为 public 或者 protected。因为如果为private则不能被子类继承,如果子类不能继承该方法就无法实现它,通常情况下我们会将修饰词设为 public。

  Java通过创建对象来使用我们所定义的方法,但是抽象类是无法用来创建对象的。就好比我给你一个抽象概念:人, 你就不能给我一个具体的对象,因为不知道具有什么特定的特征。

  因为抽象类使用的目的是为了继承,所以继承他的子类必须实现其中的抽象方法,即将抽象类具体化。如果继承他的子类没有实现其中的抽象方法,那么该子类也必须为抽象类且包含未实现的抽象方法。

  综上所述,抽象类拥有这几个特征:

  1. 抽象方法必须为 public 或者 protected
  2. 抽象类不能用来创建对象
  3. 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为 abstract 类

  除此之外其他都与普通类相同。

抽象类的应用

  在了解完抽象类的概念后,来稍微实践一下!假设你是一个动物园园长,现在你的动物园里购入了四种动物——牛、羊、狗、猫。众所周知他们都会吃东西,所以每一个动物都有吃东西的方法。接下来我们将他们实现,在了解过继承之后我们可以知道他们都能继承自一个父类animals,有着一个方法eat。

class Animals {
    public String eat(){
        return "吃了一个东西";
    }
}
class Cow extends Animals{
}
class Sheep extends Animals{
}
class Cat extends Animals{
}
class Dog extends Animals{
}

我们可以很快地把它们一一实现,这样我们可以调用每一种动物的吃东西方法了。作为一个生物,还有一个基本的特征那就是叫,我们可以也把叫(shout)方法加入到他们的父类中吗?显然直接加入是不可以的,因为每一只动物叫声都不太一样。那么抽象类的作用就出来了。**我们把他的父类变为抽象类,包含一个抽象方法叫(shout)**。更改过后就可以在每一个动物中实现叫的方法了。

abstract class Animals {
    public String eat(){
        return "吃了一个东西";
    }
    abstract public String shout();
}
class Cow extends Animals{
    public String shout(){
        return "哞哞哞~";
    }
}
class Sheep extends Animals{
    public String shout(){
        return "咩咩咩~";
    }
}
class Cat extends Animals{
    public String shout(){
        return "喵喵喵~";
    }
}
class Dog extends Animals{
    public String shout(){
        return "汪汪汪~";
    }
}

看到这可能会有一个疑惑,为什么不能直接在每一种动物中编写叫的方法呢?其实是可以的,但是为什么要使用抽象类这种看似繁琐的操作呢。因为当你继承了一个抽象类,系统就会提醒你还有抽象方法没有实现。你可能会忘记实现某一个方法,但是动物不会忘记怎么叫,对吧!

  经营了不久,你发现你的动物园出现了老鼠。这时你想到了你的动物们,猫会抓老鼠,虽然是多管闲事,狗也会抓!但是并不是所有动物都会抓老鼠啊,所以不能将抓老鼠的方法放在他们的父类 animals中。这个时候接口就派上用场了。

接口

接口的定义

  接口,英文称作 interface,在软件工程中,接口泛指供别人调用的方法或者函数。从这里,我们可以体会到 Java 语言设计者的初衷,它是对行为的抽象。在 Java 中,定一个接口的形式如下:

interface I {

}

接口的特征

  与抽象类不同的是,接口中的方法默认、隐式、且只能被 public abstract 修饰,如果运用其他修饰词去修饰其中的方法那么这个方法就会报错。 虽然我们能够在接口中定义成员变量,但是我们通常且不推荐这么做。因为方法被 abstract 修饰,所以接口中的方法都是抽象的不能有具体的实现。从这里我们可以看出接口是一个极度抽象的类型,他要比抽象类抽象的多。

  而且与抽象类不同的还有,一个类只能继承一个抽象类,但是却可以使用多个接口,具体的格式如下:

class ClassName implements Interface1, Interface2, ...{
}

接口是Java提供给开发者对对象行为的一种极度抽象方式,例如飞机和鸟都会飞,但是我们并不能把飞行作为一个抽象类,因为飞行只是一种行为。我们可以让飞机实现飞行接口,鸟实现飞行接口,然后再去定义各自的飞行方法。而飞机也分为战斗机,直升机等等,这个抽象就可以使用抽象类了。

  稍微总结一下,接口拥有以下几个特征:

  1. 接口中的方法只能被 public abstract 修饰
  2. 一个类可以使用多个接口,而只能继承一个抽象类

  再次回到我们的动物园,抓老鼠作为一种行为,我们可以使用接口来描述他。

interface CatchMice{
    public void catchs();
}

再让我们的猫狗各自实现它就可以抓老鼠啦。

interface CatchMice{
    public String catchs();
}
abstract class Animals {
    public String eat(){
        return "吃了一个东西";
    }
    abstract public String shout();
}
class Cow extends Animals{
    public String shout(){
        return "哞哞哞~";
    }
}
class Sheep extends Animals{
    public String shout(){
        return "咩咩咩~";
    }
}
class Cat extends Animals implements CatchMice{
    public String shout(){
        return "喵喵喵~";
    }
    public String catchs(){
        return "抓了一只老鼠,并喵了一声——";
    }
}
class Dog extends Animals{
    public String shout(){
        return "汪汪汪~";
    }
    public String catchs(){
        return "抓了一只老鼠,并汪了一声——";
    }
}

至此,我们的动物园就很完善了。

实践

  我们这次的作业很简单,自己设计一个用得上抽象类和接口的程序就可以啦。这里可以提供一些思路,比如不同职业的员工工作的内容不同就可以使用抽象类,某些人因为职称的关系有一些有别于不同员工的行为就可以运用上接口。

课后作业

  1. 要求编写一个类Shape包含两个方法——获取面积、获取周长。编写三个形状类——三角形,圆形矩形,包含相关的成员变量 边长。要求调用获取面积以及获取周长的方法去获取创建的对象的面积以及周长。
  2. 要求编写一个接口,包含一个printLetter的方法。编写两个类A,B实现接口printLetter,要求A的printLetter方法具体实现是打印26个大写字母,B的printLetter方法具体实现是打印26个小写字母

初めて会ったの日から 僕の心の全てを奪った