It has been asked 100 times, but they all have different answers. so I dare put this question again.
Why we can't move all the abstract method to interface?
I know there is template pattern which can be implemented using abstract method, but then it can be done using Interface as well, so why abstract method at all.
Today I am reading about this and trying to find answer.
Thanks in advance.
An interface defines a public contract for an object. I often use protected (in Java) abstract methods when using the template pattern because I don't want outside callers to be able to call the method.
There are possibly cases where you might not want an interface. What if you had something like
abstract class MyClass {
someConreteMethod() { ... }
abstract someAbstractMethod();
}
Maybe you only want implementations of MyClass to extend the abstract MyClass
In general, I don't frequently use public abstract methods, but having non-public ones is much more common.
I'm assuming you know this already but, interfaces require that the implementer overwrite the every method. Abstract classes do not. The reason this is useful is because you might want to provide one, method implementation to all the classes that extend that abstract class.
A trivial example might be a Person class
abstract class Person{
public void pumpBlood(){
//do blood pumping stuff
}
public void talk();
public void getDressed(Clothes someClothes);
}
all people should (in theory) pump blood in the same way but not all should getDressed or talk the same way. Abstract classes are good for situations like this where a concrete method may be provided.
This is an example of Template method pattern. A template made with an abstract class, with some finals method (logic that you dont want to be changed), and abstract methods(to de overriden by implementations)
public abstract class HtmlTemplate {
/**
* Get html code.
* Its final, so nobody can override.
* #return Html code.
*/
public final String getHtml() {
String html = "<html>"
+ "<head>"
+ getHead() // abstract method
+ "</head>"
+ "<body>"
+ getBody() // abstract method
+ "</body>"
+ "</html>";
return html;
}
/**
* Get head implementation.
* #return head code
*/
protected abstract String getHead();
/**
* Get body implementation.
* #return body code
*/
protected abstract String getBody() ;
}
public class MyHtmlPageImpl extends HtmlTemplate {
#Override
protected String getHead() {
return "<title>My page</title>";
}
#Override
protected String getBody() {
return "Hello world";
}
}
Related
I don't understand why we use abstract method (abstract class) while we can use empty method of non-abstract class and then we override it. Does it sound fine? I am seeking to clarify this issue.
I give 2 examples
public abstract class MyClass {public abstract void foo();}
public MyChildClass extends MyClass {public void foo() {//..TODO}}
public class MyClass {public void foo(){//empty}}
public class MyChildClass extends MyClass {public void foo() {//..TODO}}
Which one is better?
I'll start by saying that you should try to use interfaces instead of abstract classes. Abstract classes couple the subclass to the implementation of the superclass. In a language like Java, the subclass can override any method even if the superclass did not intend to do so, and most people don't qualify their methods with "do not override" all the time.
At the lowest level, abstract methods give you two concrete protections at compile time:
They force you to override the method in a subclass
They disallow the creation of the abstract class
Before listing the use cases for abstract methods, I'll just say that "common functionality" is NOT a good reason for an abstract base class. If you need common functionality, just create a class that has the common methods, and let the various classes call these functions as they see fit.
So when would you use an abstract class? Here are some examples:
Template Method
In the template method pattern, you have all of your functionality, but there's just one internal aspect that's polymorphic, so you have subclasses that override that particular aspect.
For example, if you're implementing a cache, but the cache invalidation policy is polymorphic, you may have an abstract invalidate() method that is called internally by other methods, but it's up to subclasses to implement invalidate().
If there is a preferred default cache invalidation policy, then invalidate() could implement that default. But if that default is downright destructive in some cases, then it shouldn't be a default - it should be abstract, and the code that creates the cache should be forced to explicitly choose the invalidation policy.
This can also be achieved by passing an Invalidator class to the constructor (Strategy pattern), but if the invalidation logic needs to call methods of the cache, it's better to make those method protected and call them from a subclass (i.e. Template Method pattern).
Default implementation of other methods
In languages where interfaces cannot have default methods (e.g. Java 7), you can emulate it using abstract classes. All the interface methods will be abstract, but the default methods would be regular public methods.
Common Interface and Functionality
This is just a more generic version of the template method pattern. The difference is that the polymorphic methods are part of the API.
If your common functionality has a lot of overlap with the functionality you want to expose, and you don't want mountains of boilerplate code, you use an abstract class. For example:
interface File {
abstract Buffer read(int size);
abstract void write(Buffer buf);
abstract long getSize();
abstract void setSize();
// ... get/set creation time, get/set modification time, get
// file type etc.
abstract long getOwner();
abstract void setOwner(long owner);
}
abstract class AbstractFile extends File {
DataMap dataMap;
MetadataMap metaMap;
protected getDiskMap() { return dataMap; }
protected getMetaMap() { return metaMap; }
public Buffer read(int size) { /* loop here */ }
public void write(Buffer buf) { /* loop here */ }
public long getSize() { /* logic */ }
public void setSize() { /* logic */ }
// ... implementation of get/set creation time, get/set modification
// time, get file type etc.
}
abstract class HardDriveFile extends AbstractFile {
OwnershipMap ownerMap;
abstract long getOwner() { /* logic */ }
abstract void setOwner(long owner) { /* logic */ }
}
abstract class ThumbDriveFile extends AbstractFile {
// thumb drives have no ownership
abstract long getOwner() { return 0; }
abstract void setOwner(long owner) { /* no-op */ }
}
abstract class SomeOtherfile extends AbstractFile {
...
}
If we cut the middleman and have HardDriveFile and ThumbDriveFile (and possibly other types of files) implement File and spell out all the common methods, each calling a method of some common class, we would get mountains and mountains of boilerplate. So we inherit from an abstract base class, that has the abstract methods we want to specialize (e.g. based on the existence of an ownership map).
The naive thing to do would be to combine File and AbstractFile into a single class, which is where you'd get the abstract methods getOwner() and setOwner(), but it's better to hide abstract classes behind actual interfaces, to prevent the coupling between consumers of an API and the abstract class.
As far as I've understood in Dart is possible to use abstract classes to declare "interfaces" or "protocols" (if you come from objective-c).
Anyway I'm having trouble in finding a way to declare an optional method in the abstract class/interface.
If I declare a method in the abstract class A, and let the concrete class B implement A, I get a warning in the compiler.
I'd like to be able to declare a method as optional or at least to provide a default implementation without needing to "re-declare" it in a class that implements my interface.
abstract class A{
void abstractMethod();
}
class B implements A{
//not implementing abstract method here gives a warning
}
That's not how interfaces work. If your class states to implement an interface, then this is what it has to do.
You can split the interface
abstract class A {
void abstractMethod();
}
abstract class A1 extends A {
void optionalMethod();
}
class B implements A {
//not implementing abstract method here gives a warning
}
only when it states to implement A1 it has to implement optionalMethod.
Alternatively you can extend the abstract class
abstract class A{
void abstractMethod();
void optionalMethod(){};
}
class B extends A {
//not implementing abstract method here gives a warning
}
then only abstractMethod needs to be overridden because A doesn't provide an implementation.
Abstract methods defined in classes cannot be marked as optional. (At least not in the regular Dart language, I don't know of annotations that might support something like this.)
Any class that implements an interface must provide an implementation of all abstract methods, but, those method implementations may trivially throw an error to indicate that the method is not available.
Throw UnimplementedError if the implementing class is incomplete and the proper implementation is to be added later
Throw UnsupportedError if the implementing class does not intend to implement the method.
Note that UnimplementedError implements UnsupportedError.
Obviously you have to be judicious about what you choose to not implement. If it's in code that is not intended to be shared you can get away only implementing methods that you explicitly know are required. If it's in a library package intended to be shared with others you would need a good reason to not implement a method, and that reason should be well documented.
Example code:
abstract class A {
void abstractMethod();
}
class B implements A {
void abstractMethod() { throw new UnimplementedError(...); }
// or
void abstractMethod() { throw new UnsupportedError(...); }
}
See:
https://api.dartlang.org/stable/1.18.1/dart-core/UnimplementedError-class.html
https://api.dartlang.org/stable/1.18.1/dart-core/UnsupportedError-class.html
I read many posts about the "Interface" and "Abstract Class"
Basically, we use "Abstract Class" when we talking about the characteristic of the Object.
And we use "Interface" when we taling about what the object capable can do.
But it still confuse so I make up an example for myself to practice.
so now I thinking of a Object 'Cargo;
public abstract class cargo {
protected int id;
public abstract int getWidth(int width);
public abstract int setWidth(int width);
public abstract int setHeight(int h);
public abstract int getHeight(int h);
public abstract int setDepth(int d);
public abstract int getDepth(int d);
public abstract int volume(int w,int h,int d);
public int getId(){
return this.id;
}
public abstract int setId();
public abstract void setBrand();
public abstract void getBrand( );
.....so on , still have a lot of characteristic of a cargo
}
//in the other class
public class usaCargo extends cargo{
....
private
}
So here is few Question about my design.
1.So in the real programming project world, are we actually doing like above? for me i think it's ok design, we meet the basic characteristic of cargo.
if we setup "private id" , then we actually can't use "id" this variable in any subclass because it's private, so is that mean every variable we defined in abstract class must be either public/ protected?
can someone give some suitable example so my cargo can implement some interface?
public interface registration{
public void lastWarrantyCheck();
}
But seems not suitable here...
we dont usually define variable inside interface, do we ??
I try to gain more sense on OOP . Forgive my long questions.
You would define variables in the Abstract class so that methods defined in the abstract class have variables to use. The scope of those variables depend on how you want concrete classes to access those variables:
private should be used when you want to force a concrete class to go through a getter or setter defined in the abstract class.
protected should be used when you want to give the concrete class direct access to the variable.
public should be used when you want the variable to be accessible by any class.
A reasonable interface that a Cargo object might implement could be Shippable as in how to move the cargo from a source to a destination. Some cargo may be shipped via freight train, some might be shippable by airplane, etc. It is up to the concrete class to implement Shippable and define just how that type of cargo would be shipped.
public interface Shippable {
public void ship();
}
Lastly a variable defined in an interface must be public static and final meaning it would be a constant variable.
Hope this clears it up for you!
Abstract classes can contain implementation, so they can have private variables and methods. Interfaces on the other hand cannot.
You can find some examples on how to implement interfaces here. However, I included how you would implement your registration example below.
public class Cargo implements Registration{
public void lastWarrantyCheck(){
System.out.println("Last warranty check");
}
}
Interface variables are possible, but they should only include constant declarations (variable declarations that are declared to be both static and final). More information about this can be found here.
Variables in an abstract class may be declared as protected, and they will only be available within it and any extending classes. Private variables are never accessible inside extending classes.
Interfaces provide a list of functions that are required by the classes that implement them. For example, you might use an interface hasWarranty to define all the functions that an object would need to handle warranty-related activities.
public interface hasWarranty {
public void lastWarrantyCheck();
public void checkWarranty();
}
Then, any objects that need to perform warranty-related activities should implement that interface:
// Disclaimer: been away from Java for a long time, so please interpret as pseudo-code.
// Will compile
public class Car implements hasWarranty {
public void lastWarrantyCheck() {
... need to have this exact function or program won't compile ...
}
public void checkWarranty() {
... need to have this exact function or program won't compile ...
}
}
// Missing one of the required functions defined in hasWarranty
public class Bus implements hasWarranty {
public void lastWarrantyCheck() {
... need to have this exact function or program won't compile ...
}
}
Only constants, really, as variables declared in an interface are immutable and are shared by all objects that implement that interface. They are implicitly "static final".
I have an abstract base class and an implementation class like:
public abstract class Base
{
public Base getInstance( Class<? extends Base> clazz )
{
//expected to return a singleton instance of clazz's class
}
public abstract absMeth();
}
public A extends Base
{
//expected to be a singleton
}
In this example I can make A to be a singleton and even write getInstance in Base to return a singleton object of A for every call, doing this way:
public abstract class Base
{
public Base getInstance( Class<? extends Base> clazz )
{
try
{
return clazz.getDeclaredMethod("getInstance").invoke(null,null);
}
}
public abstract void absMeth();
}
public A extends Base
{
private static A inst;
private A(){}
public static A getInstance( )
{
if( inst!= null)
inst = new A();
return inst;
}
public void absMeth(){
//...
}
}
But my concern is how do I ensure that if somebody writes another class class B extends Base it should also be a singleton and it necessarily implements a static method called getInstance?
In other words I need to enforce this as a specification for all classes extending with the Base class.
You cannot trust classes that extend you to create a single instance of themselves1: even if you could somehow ensure that they all implement getInstance, there is no way to tell that inside that method they check inst before constructing a new instance of themselves.
Stay in control of the process: create a Map<Class,Base>, and instantiate the class passed in through reflection2. Now your code can decide whether to create an instance or not, without relying on the getInstance of a subclass.
1 A popular saying goes, "If you want a job done right, do it yourself."
2 Here is a link describing a solution based on setAccessible(true)
Singleton is a design pattern, not a language feature. It is pretty much impossible to somehow enforce it on the inheritance tree through syntax.
It certainly is possible to require all subclasses to implement a method by declaring it abstract but there is no way to control implementation details. Singleton is all about implementation details.
But why is this a concern at all? Do not make your app dependant on internal details of someone else's code. It is Bad Design™ and having this issue is a sure sign of it. Code against a well-defined interface and avoid relying on internal details.
i have Abstract class
Public class Abstract baseClass
{
public abstract string GetString();
public abstract string GetString1();
}
public class DerivedClass : baseClass
{
public override string GetString()
{
return "test data";
}
public override string GetString1()
{
throw new NotImplementedException();
}
}
In above line of code, i have to implement both abstract method in derived class. But due to some reason i don't want to implement all methods, just one of them like GetString() only. How can it be done?
Thanks
If DerivedClass is going to offer common functionality to other classes, you can mark it as abstract, implement one of the methods here, and then inheritors will only have to implement the remaining method.
If you aren't going to support the other method in a given implementation, you still have to expose the method in your class, but similar to what you have here, you would typically throw a NotSupportedException. For void methods, you could simply return (do nothing).
Finally, if you want to separate out the things that have both methods and those that have only one, you can use interfaces.
public interface IBase
{
string GetString();
}
public interface IBasePlus : IBase
{
string GetStringPlus();
}
You can have one class that implements IBasePlus, but you can supply this to methods that take a parameter of type IBase, in which case you won't see the extra method.
Generally, if you don't implement all the abstract methods then your new class is also an abstract class. To get a concrete class, you need all the methods to be implemented. If you only want/need to implement a subset of the methods, consider using multiple interfaces (one interface with GetString and another with GetString1) rather than an abstract class. Then you can just implement the interfaces with the methods you want to use in the class.
Take the abstract keyword off the other method and provide a default implementation in the base class