I understand what an abstract class is in OOP paradigm. Yeah an abstract class is an incomplete type, cannot be instantiated.
Subclasses of the abstract class can extend the superclass and so on, and call a method through using a base type variable. But that is what I don't get.
I was reading the book, and the author said using a Superclass variable to reference a subclass and calling a common method calls the correct method. And yeah that's true. For example this little code I wrote:
public class ObjectOne extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public class SuperObject {
public String objectString()
{
return "SuperObject" ;
}
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem:arr)
{
out.println(elem.objectString()) ;
}
}
}
Em, so when main executes the correct methods are called for the objects using just the reference type. My question is so what is the point of an abstract class? Polymorphism works regardless of whether the method or class is abstract.
Unlike C++, polymorphism works only when you specify it. For Java, it works apparently all the time.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice? Can someone clarify thanks.
I'm not sure you understand what an abstract class is, as none of the classes in your example are abstract, and nothing in there is an interface either. What you are doing is extending an instantiable class. Without the abstract keyword there is nothing to stop me doing:
SuperObject obj = new SuperObject();
I think a better example would be to illustrate how abstract classes are used. What they are commonly used to do is to provide a common method implementation. If a number of classes implement some interface, but all of them implement the same method in the same way using the same code, then what is commonly done is to create an abstract class that contains the common implementation, and get all of the concrete implementations to extend that class. This facilitates code reuse, and decreases the likelihood that one developer will change the common method implementation for one class, but forget the others. For example..
public class ObjectOne extends Thing {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends Thing {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends Thing {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public abstract class Thing implements SuperObject {
public String alwaysTheSame() {
return "The same thing";
}
}
public interface SuperObject {
public String objectString();
public String alwaysTheSame();
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem : arr)
{
out.println(elem.alwaysTheSame());
out.println(elem.objectString()) ;
}
}
}
What we have done here is introduce an abstract class Thing, which provides a method implementation that is common to all 3 implementations of SuperObject (which is now an interface). This means we don't have to write the same code again in three different places in order to to fully implement the SuperObject interface in each one of our concrete classes.
In addition to this, you can also extend non final classes. You may wish to do this in order to override the default behaviour of one or methods on the concrete class, or to decorate the the class with additional methods. Of course, when you are designing a class hierarchy from scratch you don't stick concrete classes in it that then get extended by other classes, as it's generally considered a bad code smell. However, few of us work with totally new written-from-scratch codebases, and must adapt an exiting codebase to new requirements. Extending a concrete class is one tool in the toolbox to do this.
EDIT: Misunderstood what the OP was asking, but the last paragraph above is relevant.
Let's say you want to deploy an application on an Ipad, Android, Iphone and Desktop application.
You work on an important part that will do 95% of the job in an abstract class. Then you create 4 other small classes that will implement the abstract method differently for each device.
That way, you won't repeat 95% of the work, and each device will instanciate his own class, that extends the abstract common class.
Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.
Here's a good detailed explanation: (extracted from here)
Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks.
Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.
You also don't have to implement certain methods in abstract classes. You can decide what have to be declared in Subclasses and what you want declare in the Superclass.
Look at OutputStream for example:
public abstract void write(int i) throws IOException;
public void write(byte abyte0[]) throws IOException {
write(abyte0, 0, abyte0.length);
}
public void write(byte abyte0[], int i, int j) throws IOException {
if(abyte0 == null)
throw new NullPointerException();
if(i < 0 || i > abyte0.length || j < 0 || i + j > abyte0.length || i + j < 0)
throw new IndexOutOfBoundsException();
if(j == 0)
return;
for(int k = 0; k < j; k++)
write(abyte0[i + k]);
}
You have an abstract write method (because you don't knwo where the OutputStream is going to) but all other extra write methods are not abstract and forwarded to this methods. So you only have to declare one method in the Subclass and have some methods "extra" without having to implement it in every Subclass.
You may want a class not to have any instances.
For example assume you have a Person class and two classes derived from it Student and Teacher. In this case you may not want to have any objects created from Person class as it may not have any meaning for your program.
The "point" is to enforce a class hierarchy, potentially with some functionality provided by base class(es), and force some behavior to be implemented by sub-classes.
You would use an abstract class in cases where you do want to specify certain behaviour but don't want anybody to instatiate it directly but having to subclass it.
An abstract class can be full bodied or the skeleton for the subclass. You define your template in the abstract class and its left for the subclass to extend and implement the methods defined in the superclass.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice?
My answer is yes to everything that you said.
Along with what others have said, you may be using a library written by someone else, where you don't have access to the source code, but want to change it's behavior.
Related
During one of my interview, I was asked "If we can instantiate an abstract class?"
My reply was "No. we can't". But, interviewer told me "Wrong, we can."
I argued a bit on this. Then he told me to try this myself at home.
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
Here, I'm creating instance of my class and calling method of abstract class. Can anyone please explain this to me? Was I really wrong during my interview?
Here, i'm creating instance of my class
No, you are not creating the instance of your abstract class here. Rather you are creating an instance of an anonymous subclass of your abstract class. And then you are invoking the method on your abstract class reference pointing to subclass object.
This behaviour is clearly listed in JLS - Section # 15.9.1: -
If the class instance creation expression ends in a class body, then
the class being instantiated is an anonymous class. Then:
If T denotes a class, then an anonymous direct subclass of the class named by T is declared. It is a compile-time error if the
class denoted by T is a final class.
If T denotes an interface, then an anonymous direct subclass of Object that implements the interface named by T is declared.
In either case, the body of the subclass is the ClassBody given in the class instance creation expression.
The class being instantiated is the anonymous subclass.
Emphasis mine.
Also, in JLS - Section # 12.5, you can read about the Object Creation Process. I'll quote one statement from that here: -
Whenever a new class instance is created, memory space is allocated
for it with room for all the instance variables declared in the class
type and all the instance variables declared in each superclass of the
class type, including all the instance variables that may be hidden.
Just before a reference to the newly created object is returned as the
result, the indicated constructor is processed to initialize the new
object using the following procedure:
You can read about the complete procedure on the link I provided.
To practically see that the class being instantiated is an Anonymous SubClass, you just need to compile both your classes. Suppose you put those classes in two different files:
My.java:
abstract class My {
public void myMethod() {
System.out.print("Abstract");
}
}
Poly.java:
class Poly extends My {
public static void main(String a[]) {
My m = new My() {};
m.myMethod();
}
}
Now, compile both your source files:
javac My.java Poly.java
Now in the directory where you compiled the source code, you will see the following class files:
My.class
Poly$1.class // Class file corresponding to anonymous subclass
Poly.class
See that class - Poly$1.class. It's the class file created by the compiler corresponding to the anonymous subclass you instantiated using the below code:
new My() {};
So, it's clear that there is a different class being instantiated. It's just that, that class is given a name only after compilation by the compiler.
In general, all the anonymous subclasses in your class will be named in this fashion:
Poly$1.class, Poly$2.class, Poly$3.class, ... so on
Those numbers denote the order in which those anonymous classes appear in the enclosing class.
The above instantiates an anonymous inner class which is a subclass of the my abstract class. It's not strictly equivalent to instantiating the abstract class itself. OTOH, every subclass instance is an instance of all its super classes and interfaces, so most abstract classes are indeed instantiated by instantiating one of their concrete subclasses.
If the interviewer just said "wrong!" without explaining, and gave this example, as a unique counterexample, I think he doesn't know what he's talking about, though.
= my() {}; means that there's an anonymous implementation, not simple instantiation of an object, which should have been : = my(). You can never instantiate an abstract class.
Just observations you could make:
Why poly extends my? This is useless...
What is the result of the compilation? Three files: my.class, poly.class and poly$1.class
If we can instantiate an abstract class like that, we can instantiate an interface too... weird...
Can we instantiate an abstract class?
No, we can't. What we can do is, create an anonymous class (that's the third file) and instantiate it.
What about a super class instantiation?
The abstract super class is not instantiated by us but by java.
EDIT: Ask him to test this
public static final void main(final String[] args) {
final my m1 = new my() {
};
final my m2 = new my() {
};
System.out.println(m1 == m2);
System.out.println(m1.getClass().toString());
System.out.println(m2.getClass().toString());
}
output is:
false
class my$1
class my$2
You can simply answers, in just one line
No, you can never instance Abstract Class
But, interviewer still not agree, then you can tell him/her
all you can do is, you can create an Anonymous Class.
And, according to Anonymous class, class declared and instantiate at the same place/line
So, it might be possible that, interviewer would be interested to check your confidence level and how much you know about the OOPs .
The technical part has been well-covered in the other answers, and it mainly ends in:
"He is wrong, he doesn't know stuff, ask him to join SO and get it all cleared :)"
I would like to address the fact(which has been mentioned in other answers) that this might be a stress-question and is an important tool for many interviewers to know more about you and how do you react to difficult and unusual situations. By giving you incorrect codes, he probably wanted to see if you argued back. To know whether you have the confidence to stand up against your seniors in situations similar to this.
P.S: I don't know why but I have a feeling that the interviewer has read this post.
Abstract classes cannot be instantiated, but they can be subclassed. See This Link
The best example is
Although Calender class has a abstract method getInstance(), but when you say Calendar calc=Calendar.getInstance();
calc is referring to the class instance of class GregorianCalendar as "GregorianCalendar extends Calendar "
Infact annonymous inner type allows you to create a no-name subclass of the abstract class and an instance of this.
Technical Answer
Abstract classes cannot be instantiated - this is by definition and design.
From the JLS, Chapter 8. Classes:
A named class may be declared abstract (ยง8.1.1.1) and must be declared
abstract if it is incompletely implemented; such a class cannot be
instantiated, but can be extended by subclasses.
From JSE 6 java doc for Classes.newInstance():
InstantiationException - if this Class represents an abstract class, an interface, an array
class, a primitive type, or void; or if the class has no nullary constructor; or if the
instantiation fails for some other reason.
You can, of course, instantiate a concrete subclass of an abstract class (including an anonymous subclass) and also carry out a typecast of an object reference to an abstract type.
A Different Angle On This - Teamplay & Social Intelligence:
This sort of technical misunderstanding happens frequently in the real world when we deal with complex technologies and legalistic specifications.
"People Skills" can be more important here than "Technical Skills". If competitively and aggressively trying to prove your side of the argument, then you could be theoretically right, but you could also do more damage in having a fight / damaging "face" / creating an enemy than it is worth. Be reconciliatory and understanding in resolving your differences. Who knows - maybe you're "both right" but working off slightly different meanings for terms??
Who knows - though not likely, it is possible the interviewer deliberately introduced a small conflict/misunderstanding to put you into a challenging situation and see how you behave emotionally and socially. Be gracious and constructive with colleagues, follow advice from seniors, and follow through after the interview to resolve any challenge/misunderstanding - via email or phone call. Shows you're motivated and detail-oriented.
It is a well-established fact that abstract class can not be instantiated as everyone answered.
When the program defines anonymous class, the compiler actually creates a new class with different name (has the pattern EnclosedClassName$n where n is the anonymous class number)
So if you decompile this Java class you will find the code as below:
my.class
abstract class my {
public void mymethod()
{
System.out.print("Abstract");
}
}
poly$1.class (the generated class of the "anonymous class")
class poly$1 extends my
{
}
ploly.cass
public class poly extends my
{
public static void main(String[] a)
{
my m = new poly.1(); // instance of poly.1 class NOT the abstract my class
m.mymethod();
}
}
About Abstract Classes
Cannot create object of an abstract class
Can create variables (can behave like datatypes)
If a child can not override at least of one abstract method of the parent, then child also becomes abstract
Abstract classes are useless without child classes
The purpose of an abstract class is to behave like a base. In inheritance hierarchy you will see abstract classes towards the top.
No, you can't instantite an abstract class.We instantiate only anonymous class.In abstract class we declare abstract methods and define concrete methods only.
Extending a class doesn't mean that you are instantiating the class. Actually, in your case you are creating an instance of the subclass.
I am pretty sure that abstract classes do not allow initiating. So, I'd say no: you can't instantiate an abstract class. But, you can extend it / inherit it.
You can't directly instantiate an abstract class. But it doesn't mean that you can't get an instance of class (not actully an instance of original abstract class) indirectly. I mean you can not instantiate the orginial abstract class, but you can:
Create an empty class
Inherit it from abstract class
Instantiate the dervied class
So you get access to all the methods and properties in an abstract class via the derived class instance.
It's impossible to instantiate an abstract class.
What you really can do, has implement some common methods in an abstract class and let others unimplemented (declaring them abstract) and let the concrete descender implement them depending on their needs.
Then you can make a factory, which returns an instance of this abstract class (actually his implementer). In the factory you then decide, which implementer to choose. This is known as a factory design pattern:
public abstract class AbstractGridManager {
private LifecicleAlgorithmIntrface lifecicleAlgorithm;
// ... more private fields
//Method implemented in concrete Manager implementors
abstract public Grid initGrid();
//Methods common to all implementors
public Grid calculateNextLifecicle(Grid grid){
return this.getLifecicleAlgorithm().calculateNextLifecicle(grid);
}
public LifecicleAlgorithmIntrface getLifecicleAlgorithm() {
return lifecicleAlgorithm;
}
public void setLifecicleAlgorithm(LifecicleAlgorithmIntrface lifecicleAlgorithm) {
this.lifecicleAlgorithm = lifecicleAlgorithm;
}
// ... more common logic and getters-setters pairs
}
The concrete implementer only needs to implement the methods declared as abstract, but will have access to the logic implemented in those classes in an abstract class, which are not declared abstract:
public class FileInputGridManager extends AbstractGridManager {
private String filePath;
//Method implemented in concrete Manager implementors
abstract public Grid initGrid();
public class FileInputGridManager extends AbstractGridManager {
private String filePath;
//Method implemented in concrete Manager implementors
abstract public Grid initGrid();
public Grid initGrid(String filePath) {
List<Cell> cells = new ArrayList<>();
char[] chars;
File file = new File(filePath); // for example foo.txt
// ... more logic
return grid;
}
}
Then finally the factory looks something like this:
public class GridManagerFactory {
public static AbstractGridManager getGridManager(LifecicleAlgorithmIntrface lifecicleAlgorithm, String... args){
AbstractGridManager manager = null;
// input from the command line
if(args.length == 2){
CommandLineGridManager clManager = new CommandLineGridManager();
clManager.setWidth(Integer.parseInt(args[0]));
clManager.setHeight(Integer.parseInt(args[1]));
// possibly more configuration logic
...
manager = clManager;
}
// input from the file
else if(args.length == 1){
FileInputGridManager fiManager = new FileInputGridManager();
fiManager.setFilePath(args[0]);
// possibly more method calls from abstract class
...
manager = fiManager ;
}
//... more possible concrete implementors
else{
manager = new CommandLineGridManager();
}
manager.setLifecicleAlgorithm(lifecicleAlgorithm);
return manager;
}
}
The receiver of AbstractGridManager would call the methods on him and get the logic, implemented in the concrete descender (and partially in the abstract class methods) without knowing what is the concrete implementation he got. This is also known as inversion of control or dependency injection.
You can say: we can't instantiate an abstract class, but we can use new keyword to create an anonymous class instance by just adding {} as implement body at the the end of the abstract class.
No, we can't create the object of abstract class, but create the reference variable of the abstract class. The reference variable is used to refer to the objects of derived classes (Sub classes of Abstract class)
Here is the example that illustrates this concept
abstract class Figure {
double dim1;
double dim2;
Figure(double a, double b) {
dim1 = a;
dim2 = b;
}
// area is now an abstract method
abstract double area();
}
class Rectangle extends Figure {
Rectangle(double a, double b) {
super(a, b);
}
// override area for rectangle
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Figure {
Triangle(double a, double b) {
super(a, b);
}
// override area for right triangle
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
class AbstractAreas {
public static void main(String args[]) {
// Figure f = new Figure(10, 10); // illegal now
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref; // this is OK, no object is created
figref = r;
System.out.println("Area is " + figref.area());
figref = t;
System.out.println("Area is " + figref.area());
}
}
Here we see that we cannot create the object of type Figure but we can create a reference variable of type Figure. Here we created a reference variable of type Figure and Figure Class reference variable is used to refer to the objects of Class Rectangle and Triangle.
Actually we can not create an object of an abstract class directly. What we create is a reference variable of an abstract call. The reference variable is used to Refer to the object of the class which inherits the Abstract class i.e. the subclass of the abstract class.
I have an abstract class inherited by two concrete classes.
public abstract class AbstractClass {
public abstract void operation1();
}
public class ConcreteClassA extends AbstractClass {
#Override
public void operation1() {
// Do work
}
public void operation2() {
// Do some other work
}
}
public class ConcreteClassB extends AbstractClass {
#Override
public void operation1() {
// Do work
}
}
Now, to take advantage of dynamic binding I create two objects while programming to the interface.
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
But this does not allow me to call method operation2() on classA. I can fix this by using a downcast.
((ConcreteClassA) classA).operation2();
But downcasts are considered ugly in OOP especially when you have to use them a lot. Alternatively, I can give up programming to the interface.
private ConcreteClassA classA = new ConcreteClassA();
But then I lose the dynamic binding. Another option is to move operation2() to the AbstractClass so that I can restore the dynamic binding.
public abstract class AbstractClass {
public abstract void operation1();
public abstract void operation2();
}
But then ConcreteClassB needs to override operation2() leaving the implementation empty since this class does not need this method.
Lastly, I could move operation2() to the AbstractClass and provide a default implementation which may be overridden or not.
public abstract class AbstractClass {
public abstract void operation1();
public void operation2() {
// Some default implementation
}
}
But this gives classB access to operation2() which I would rather avoid.
There does not seem to be a clean solution to call subclass specific methods while maintaining dynamic binding at the same time. Or is there?
There are at least a few ways to deal with this circumstance and, really, the right one depends on your particular requirements.
Ask yourself, "are both operation1 and operation2 part of the contract specified by my type?"
If the answer is clearly no, then you should not pollute the contract of your type by adding collateral methods to it. You should next ask yourself, "why am I not using interfaces to specify separate types, eg.: instead of AbstractClass, why am I not using MyInterface1 and MyInterface2 (each with its own separate contract)? Interfaces provide a limited form of multiple inheritance, and your implementing classes can implement any and all interfaces that pertain to it. This is a strategy commonly used by the Java Platform Libraries. In this circumstance, explicit casting to the type whose contract you want to use is exactly the right thing to do.
If the answer is clearly yes, then you should have both methods in your type ... but you should still ask yourself, "why am I not specifying my type with an interface"? In general, you should specify types with interfaces rather than abstract classes, but there are reasons to use the latter.
If the answer is somewhere in between, then you can consider specifying optional methods in your type. These are methods which are included in the contract of your type, but which implementing classes are not required to implement. Before Java 8, each implementing type would need to throw a UnsupportedOperationException for any optional methods that it did not implement. In Java 8, you can do something like this for optional methods:
======
public interface MyType {
void contractOperation1();
default void optionalOperation2() {
throw new UnsupportedOperationException();
}
}
A class that implements this interface will need to provide an implementation for contractOperation1(). However, the class will not need to provide an implementation for optionalOperation2() and if this method is invoked on an implementing class that has provided no implementation of its own, then the exception is thrown by default.
abstract class don't have the object,we just create the reference of that class and use it.
like:
instead of this-
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
use this one
private AbstractClass classA;
private AbstractClass classB;
If we will create an object of the abstract class and calls the method having no body(as the method is pure virtual) it will give an error. That is why we cant create object of abstract class. Here is a similar StackOverflow question. In short, it is legal to have a public constructor on an abstract class.
more details are here:about abstraction instance
This question already has answers here:
What is the difference between an interface and abstract class?
(38 answers)
Closed 8 years ago.
I have two programs one implemented using interfaces and the other implemented using only classes -
I've read that the advantage of using an interface is that it can provide it's own implementation of methods of super class but that can be done using abstract classes or method overriding. What purpose does interfaces serve?
In what kind of hierarchy and situation using interface will be most beneficial?
INTERFACE
interface Shape
{
void area(int x, int y);
}
class Rectangle implements Shape
{
#Override
public void area(int length, int breadth)
{
System.out.println(length*breadth);
}
}
class Triangle implements Shape
{
#Override
public void area(int base, int height)
{
System.out.println(base*height);
}
}
public class ShapeUsingInterface
{
public static void main(String X[])
{
Rectangle r = new Rectangle();
Triangle t = new Triangle();
r.area(5, 4);
t.area(6, 3);
}
}
CLASS
class Shape
{
void Area(int x, int y)
{
System.out.println(x*y);
}
}
class Rectangle extends Shape
{
}
class Triangle extends Shape
{
#Override
void Area(int base, int height)
{
System.out.println((0.5)*base*height);
}
}
public class CalculateArea
{
public static void main(String X[])
{
Rectangle r = new Rectangle();
Triangle t = new Triangle();
r.Area(4, 5);
t.Area(6, 8);
}
}
To explain why interfaces are used, you have to first understand a problem with inheritance. It's called the Diamond Problem. Simply, if a class, D inherits from two classes B and C, and B and C both inherit from the same class A, which implementation of the methods from A does D get?
What we're left with is a method ambiguity that Java does not like! So the way of preventing this is to make sure that D can only ever have one superclass, so it could inherit from either A, B or C, but never more than one. So that prevents the problem, but we lose all of the perks that multiple inheritance offers!
Enter the Interface. This allows us to have the perks of multiple inheritance (referencing the single class as various different types) and still avoid the diamond problem, because the implementing class provides the method. This removes the method ambiguity.
This means that, for example:
public abstract class MyClass {
public void doSomething();
}
public class MyConcreteClass extends MyClass {
public void doSomething() {
// do something
}
}
You can either refer to an instance of MyConcreteClass as
MyClass class = new MyConcreteClass();
or
MyConcreteClass class = new MyConcreteClass();
But never anything else, given this implementation. You can't extend more classes because you'll potentially get the diamond problem, but you CAN include an Interface
public class MyConcreteClass extends MyClass implements Serializable {
}
All of a sudden, you can say..
Seralizable myClass = new MyConcreteClass();
Because myClass is a Serializable. This is excellent for decoupling classes from one another, when a method might not need to know that it is an instance of MyConcreteClass, only that it has a necessary subset of methods.
In short: You can implement many interfaces, but you can only inherit one class.
Interface defines the contract. Say for example:
interface MusicPlayer
{
public void shuffle();
}
Now each class implementing the interface can have their own algorithm for implementing shuffle method, its upto them. Abstract class is similar to interface, where an abstract class defines few methods to be common and leave other methods to be implemented in our own way. Like
abstract class MusicPlayer
{
public void turnOff()
{
//kill the app
}
abstract public void shuffle();
}
And using interfaces you can implement multiple interfaces but only extend a single class.
I would say that in your example Shape should definitely not be class, but interface. You have provided default implementation for area calculation as x*y, hovewer in case of most shapes this implementation is not correct.
If you will add new shape you will inherit method with incorrect implementation. You will have to remember to check all methods in all classes to validate inherited methods. In case of interface you can't make this mistake.
You can see interfaces as a social contract which states that all the classes who implement the interface should define the methods declared in the interface. This creates continuity between all the classes which implement them, and that's awesome if you want all those classes to have the same behaviors. Since an interface does not declare the implementation itself, it leaves that to the class that implements it. This way you create for example many machines which all have a start button, something you would likely want them all to have. Better said required them all to have, the social contract makes sure this is the case since you must implement every method of an interface! That is required by the compiler.
A class which overrides all the methods in of an other class (by extending the class and implementing in on its one) does not truly say that it will always truly keep this promise. The benefit of knowing that the class will be loyal is gone and you obscure the logic behind it. It would be less clear to see if all methods are overridden or not, and that's bad practice. Why not make your logic clear and actually implement the social contract with an interface.
Abstract classes are a little bit different in that they also implement methods, as seen by normal classes, and also work as an interface because they also require that you implement declared but unimplemented methods. In java 8 interfaces can do this too.
I am trying to pass a Class to a method. The Class changes as the program runs, so I'd like to reuse the same method through out my program instead of calling the same functions throughout my resetWords() method.
Here is where I am stuck:
private void getWords(Class c) {
singles = c.getSingleSyllables();
doubles = c.getDoubleSyllables();
triples = c.getTripleSyllables();
quadruples = c.getQuadrupleSyllables();
quintuples = c.getQuintupleSyllables();
}
private void resetWords() {
if (generated.equals("SOMETHING")) {
Something c = new Something();
getWords(c);
}
else if (generated.equals("ANOTHER")) {
Another c = new Another();
getWords(c);
}
}
I think what you are looking for is an interface. You should declare an interface like this:
public interface Passable
{
public List<String> getSingleSyllables();
public List<String> getDoubleSyllables();
// ...
}
Then, let Something and Another implement them:
public class Something implements Passable
{
// method declarations
}
Now, change your method to this:
private void getWords (Passable c) {
singles = c.getSingleSyllables();
doubles = c.getDoubleSyllables();
triples = c.getTripleSyllables();
quadruples = c.getQuadrupleSyllables();
quintuples = c.getQuintupleSyllables();
}
A little vague what you're asking but perhaps create an Interface that defines all of the getXSyllables() methods. Have your classes (Something and Another) implement that Interface. Finally, define getWords as private void getWords(YourInterface c).
You're confusing classes, and objects.
What you're passing to getWords() is an object. In the first case, it's an object of type Something. In the second case, it's an object of type Another.
The only way for such code to work is to define a common base class or interface for Something and Another (let's call it HavingSyllabes), containing the 5 methods used in getWords(): getSingleSyllables(), getDoubleSyllabes(), etc. And the signature of getWords() should be
private void getWords(HavingSyllabes c)
If the classes always implement getSingleSyllables(), getDoubleSyllables(), etc.. then you should consider inheriting from an abstract class, or implementing an interface.
Then...
private void getWords(YourInterface / YourAbstractClass foo) {
...
}
Your question does not provide enough detail to answer clearly.
Depending upon your design / end-goals, there are three concepts you should take a look at and understand:
Interfaces
Abstract Classes
Reflection
An Interface will define the methods that classes that implement the interface must provide. Each class that implements the interface must provide the code for the method.
An Abstract Class will provide a single implementation of the behavior that you are looking for.
Reflection is an advanced concept. I would recommend you stay away from it at this time - but you should be aware of it.
Given your example code, you may want to use an Abstract Class. Designed properly, you can increase flexibility/reuse by defining an interface, implementing that interface with an Abstract Class and then extending that Abstract Class as needed. Every class that extends the Abstract will pick up the default implementation you provided in the Abstract class definition; the Interface will make it easy for you to extend in the future.
First things first, please be aware I am trying to express my question as best I can with my current knowledge and vocabulary, so please excuse this...
I have an abstract class in which I want to make a method where it instantiates itself.... Of course this is impossible in an abstract class, however, what I really want is for the concrete children (those classes that "extends") to inherit this instantiation so that they then can instantiate themselves....
Basically what I want to do is this:
MyAbstract a = new this();
However this isn't allowed... Is there any way I can do what I want?
Here is some non-compiling dream-code (i.e. code I wish worked). Basically I am wanting the ConcreteChild to call a method in which it create an object of itself. The method is inherited from it's parent.
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new this();
}
}
public class ConcreteChild extends Abstract{
public static void main(String[] args) {
ConcreteChild c = new ConcreteChild();
c.instantiateMyConcreteChild();
}
}
* Additional info **
Thanks for the replies but I think I missed something vital....
Basically I wanted to pass an object's self ( "this" ) into some methods of some other classes. However, creating instantiating another object within an object is a bit backwards, I can just pass "this", right...
You can do this using reflection, something like :
Abstract a = getClass().newInstance();
This is because getClass() always returns the concrete class, so this.getClass() will return the real subclass and not the current class.
However, beware that if the subclass defines a custom constructor, having more or less parameters than your abstract class, it could fail. Unless you specify in the documentation that subclasses must have a constructor with such given parameters ... but it's fragile anyway.
You can inspect it, using getClass().getConstructors() and see which constructors are there, and if there is the one you are expecting, or even search for a viable one, otherwise you can catch the exception thrown by newInstance(..), and wrap it in a more descriptive exception for the users, so that they understand better what they missed ... but it would still be a kind of a hack, cause there is no explicit language support for such a situation.
Another approach could be to implement Cloneable in your abstract class, and then use the clone method, but it could be overkill or even wrong if what you want is a new, clean instance.
You can't do this using an instance method. Because as the name implies an instance methods requires that the instance has already instantiated.
What you actually need to do here is to separate the non-changing internal functionality from the abstract class itself. So what I could do is to ,for e.g., have an inner class that really encapsulates the non-changing functionality like so:
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new NonChangingOperations();
}
class NonChangingOperations
{
public void operationA() {}
}
}
Infact you really dont need to keep the class NonChangingOperations as an inner class, you could make it as an external utility class with its own class hierarchy.
Are you trying to define a constructor that the subclasses of Abstract can use? If so you could simply do it the same way you define any other constructor.
public class Abstract {
Abstract() {
//set fields, etc. whatever you need to do
}
}
public class ConcreteChild extends Abstract{
ConcreteChild() {
//call superclass's constructor
super();
}
}
Could you just have this ?
public abstract class AbstractClassWithConstructor {
public AbstractClassWithConstructor() {
init();
}
protected abstract void init();
}
FYI
In the objective-c you need to set this by calling method init. The the method init() would look like this:
protected AbstractClassWithConstructor init() {
return this;
}