考えていないことがいくつかあります。抽象クラスと抽象メソッドがあります。抽象クラスは直接インスタンス化することはできません。つまり、テンプレートだけです。抽象メソッドはabstracクラスでのみ定義でき、は空の(つまりボディなし)である必要がありますが、すべてを知っています。ただし、抽象クラスは非抽象メソッドを提供できます。完璧な例は、Log4jのAppenderSkeleton
です(http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/AppenderSkeleton.htmlを参照)。
は抽象クラスです。継承する場合(あなたのクラスも抽象クラスでない限り)実装する必要がある抽象メソッド(append
)と、それが必要なインターフェイスであるAppender
の2つのメソッドがあります。またはが子クラス(close
およびrequireLayout
)に抽象として渡されたを渡した。あなたは、たとえば、いくつかのものをツイートする独自のアペンダを書きたい場合は
さて、あなたが開始することにより:
public class TweetAppender extends AppenderSkeleton {
public boolean requiresLayout() {
return false;
}
public void close() {
// do nothing
}
@Override
protected void append(LoggingEvent event) {
// take the message and tweet it!
}
}
ので、伐採に関する複雑さのすべて(のレベルを設定し、フィルタを使用して、エラーハンドラー)はあなたから離れています。実際のロギングを行うだけで、残りの部分をlog4jが処理します。もちろん、あなたが望むなら、TweetAppender
は他のメソッドを上書きすることができます。おそらく、特別なエラー処理をしたいと思うかもしれません。この場合は、setErrorHandler
を上書きする必要があるかもしれません。
Facebook用のアペンダーとSkype上のステータスを変更するアペンダーを実装したいと考えているとします。状況の更新や変更などを投稿するために、Webサービスを介してAPIを公開しているとします。まもなく、Webサービスの呼び出しなど、似たようなことがいくつかあることに気付きます。また、Skypeには何らかのフォーマットがあることに気付きましたが、Tweeterにはもう1つのフォーマットがあります。だから、賢明アップあなたとWebServiceAppenderします
今
public abstract class WebServiceAppender extends AppenderSkeleton {
public boolean requiresLayout() {
return false;
}
public final void close() {
// do extra clean up of resources
}
// make this final so no one can do strange stuff
protected final void append(LoggingEvent event) {
// do a lot of stuff, like, opening up a connection
// send an xml, close the connection and stuff...
// ...
// ready to send the message!
final String messageToSend = getFormattedMessage(event);
// send the message and do lots of complicated stuff
// ...
// close and clean up
}
// let the implementations decide on the format
protected abstract String getFormattedMessage(LoggingEvent event);
}
、あなたのTweetAppender
は抽象としてgetFormattedMessage
を宣言することにより
public class TweetAppender extends WebServiceAppender {
@Override
protected String getFormattedMessage(LoggingEvent event) {
// use tweeter's specific format
}
public boolean requiresLayout() {
return super.requiresLayout();
}
}
ようになり、WebServiceAppender
は実際にかかる実装を提供するために、任意の実装を強制されますLoggingEvent
を返し、String
を返します。また、append
とclose
メソッドをfinalと宣言することにより、WebServiceAppender
はこれらのメソッドをオーバーライドすることを禁止しています。 requireLayout
メソッドはまだオーバーライドされています。
抽象クラスを継承するクラスの別のクールな機能は、super
の使用です。親クラス 'this
と考えることができます。 TweetAppenderの場合には、requiresLayoutメソッドの実装は、このアペンダは、単に親クラスを使用してレイアウトを必要とするかどう基本的に決定するの責任を延期することを決定します。
だから、一緒にすべてを置く:
public class YourParentClass {
public void doThis() {
if (1 < 0){
int x = 34
}
}
public class YourChildClass extends YourParentClass {
@Override
public void doThis() {
// do I want to do this, or something else?
if (iGuessIWillDoThis) {
super.doThis();
} else {
// do something else
}
}
}
とにかく、私の2セントを。
Btw、C++やJavaについて話していますか?私が考える限り、Javaでは、インタフェースは抽象基本クラスよりも常に優れた設計です。 – Falmarri
@falmarri、私は同意しない、彼らは完全に異なっている。それらを一緒に使用できることに注意してください。インタフェースは振る舞いを定義するためのもので、抽象クラスは*いくつかの機能を提供するためのものですが、後で最後の詳細を埋め込むことができます。 – hvgotcodes