Java中抽象类的使用

时间:2016-01-27 13:07:27

标签: java

在Stackoverflow中,我有一个链接到下面的答案,但它提供的抽象类的定义和概念不是逻辑原因

Abstract class in Java

根据我的理解,我认为抽象类包含可重用于子类的已实现方法。

我检查了AbstractList和AbstractMap,它们的所有方法都在ArrayList和HashMap中被覆盖,但是在ArrayList或HashMap中没有使用相同的AbstractList或AbstractMap实现方法。

抽象类还有什么吗?任何人都可以让我知道

4 个答案:

答案 0 :(得分:1)

实际上抽象可能包含或不包含包含抽象方法。抽象类不能实例化,但它们可以被子类化。

为什么我们使用抽象类?

假设我们通过创建一个以名为Human的基类开始的类层次来模拟人类的行为。人类能够像说话,走路和吃饭那样做不同的事情。让我们采取说话行为(例如:greeting()方法)每个人都取决于他的国籍有不同的语言:英国男人会说:“你好”和一个弗伦什男人会说:“ Bonjour “。

所以我们知道所有的人都可以用不同的语言来打招呼!

这是抽象方法的一个很好的候选者(强制子类提供自定义实现)。  让我们看一个非常原始的Humain基类,它定义了一个用于进行问候和漫步的抽象方法:

public abstract class Human
{

    //We know that humain walk the same way so we provide 
    //method implementation at this level
    public void walk()
    {
        System.out.println('I\'m walking !');
    }

    //We don't know at this level what's the language of the humain
    public abstract void greet ();

}

//This class inherit the walk() method and provide it's
//specific implementation for the greeting() method
public class EnglishMen extends Human {

    @Override
    public abstract void greet () {
        System.out.println('Hello :) ');
    }

}

//This class inherit the walk() method and provide it's
//specific implementation for the greeting() method
public class FrenshMen extends Human {

    @Override
    public abstract void greet () {
        System.out.println('Bonjour :) ');
    }

}

现在,任何想要实例化的Humaun(如EnglishMen或FrenshMen)必须实现 t greeting方法 - 否则无法创建实例那个班。

  

注意:当抽象类是子类时,子类通常提供   其父类中所有抽象方法的实现。   但是,如果没有,则还必须声明子类   抽象。

答案 1 :(得分:0)

abstract类是一个实现对象大部分功能的类,但为您实现了关键功能。

当鼓励(或甚至预期)创建接口的实现时,通常会提供所有可能的帮助来执行此操作。这是Abstract...类非常有用的地方。它们不仅实现了接口,而且还暴露了一组必须实现的abstract方法。

考虑使用String

包含一个AbstractList的列表的此实现
class OneHelloList extends AbstractList<String> implements List<String> {

    @Override
    public int size() {
        return 1;
    }

    @Override
    public String get(int index) {
        return "Hello";
    }

}

public void test() {
    for (String s : new OneHelloList()) {
        System.out.println(s);
    }
}

了解使用非常小的代码库实现List的完整功能对我来说是多么简单。

与没有implement List的{​​{1}}我必须做的事情形成对比:

AbstractList

答案 2 :(得分:0)

抽象类与接口类似。您无法实例化它们,并且它们可能包含使用或不使用实现声明的混合方法。但是,对于抽象类,您可以声明非静态和最终的字段,并定义public,protected和private具体方法。使用接口,所有字段都自动为public,static和final,并且您声明或定义的所有方法(作为默认方法)都是公共的。此外,您只能扩展一个类,无论它是否是抽象的,而您可以实现任意数量的接口。

您应该使用哪些,抽象类或接口?

  • 如果这些语句中的任何一个适用于您的情况,请考虑使用抽象类:
    • 您希望在几个密切相关的类之间共享代码。
    • 您希望扩展抽象类的类具有许多常用方法或字段,或者需要除公共之外的访问修饰符(例如protected和private)。
    • 您想要声明非静态或非最终字段。这使您可以定义可以访问和修改它们所属对象状态的方法。
  • 如果这些陈述中的任何一个适用于您的情况,请考虑使用接口:
    • 您希望不相关的类会实现您的界面。例如,Comparable和Cloneable接口由许多不相关的类实现。
    • 您希望指定特定数据类型的行为,但不关心谁实现其行为。
    • 您希望利用类型的多重继承。

realtime-examples

abstract-class-real-time-example

答案 3 :(得分:0)

抽象类在实际实现已知但域模型(数据)未知的情况下也非常有用。例如,要插入数据库,可以编写抽象类

public abstract class DBUpdate{

protected insert(){

...//the actual implementation
}
 protected update(){

...//the actual implementation
 }
 protected delete(){

...//the actual implementation
}
//the fields of the subclasses can be obtained through reflection or some other method

现在,让我们说你有一个表格MyTable,其中包含a,b和c列,需要插入数据库

public class MyTable extends DBUpdate{

private String a;
private String b;
private String c;

 //add getters/setters here
}

现在,为了插入MyTable记录,我们应该只创建它的一个实例并调用insert()方法

....
MyTable myTable = new MyTable();
myTable.seta("a");
myTable.setb("b");
myTable.setc("c");

myTable.insert();

DBUpdate知道如何插入,更新和删除数据,但仍然需要进行子类化(基本上告诉DBUpdate需要更新哪些数据)