Accessing methods via OBJECTS vs INHERITANCE - java

Consider this child class :
public class Circle extends BasicAreas{
public static void main(String args[])
{
BasicAreas ba = new BasicAreas();
Circle c = new Circle();
c.PrintCircleArea(ba);
}
void PrintCircleArea(BasicAreas ba)
{
System.out.println("Area of circle is : "+areaCircle(3.14));
}
}
and the parent class :
class BasicAreas{
double areaCircle(double radius)
{
return 3.14 * radius * radius;
}
int areaSquare(int side)
{
return side * side;
}
int areaRectangle(int len, int breadth)
{
return len * breadth;
}
}
Now, i am pretty well confused about this... :
System.out.println("Area of circle is : "+areaCircle(3.14));
When i extend a super-class...i can access the methods of that class without using an instantiated object like above....but
when i do not extend a class, i can access its method using an object like :
System.out.println("Area of circle is : "+ba.areaCircle(3.14)); /* "ba" being object */
So my question is that when should i prefer using objects and when to use extend to access other class methods...and whats the difference between them on basic level??
learning java...so please go easy...i know the question is pretty dumb, but there is no clear answer....i am also open to possibility that this question might be conceptually wrong too!!!

So my question is that when should i prefer using objects and when to use extend to access other class methods...and whats the difference between them on basic level??
the inheritance represents a is-a relationship. but the composition represents a has-a relationship. you can choose any of these two to solve your problem but to make a good design it is important to choose between the right one.
so inheritance should be used only when a subclass is-a superclass. for example in the above example circle is a basicArea. Otherwise use composition.
you can see this article or plenty of others avaiable on net to find the differences between these two with example.

When your class is not in the inheritance hierarchy, then you should use object method. When you extend a class, then the child gets the method by default as if it is its own method. THis is because child class is susbclass of superclass. i.e. In your case, Circle IS-A BasicAreas.
When you do not extend the class, then you do not have access to method as long as you instantiate the object.

In both cases, you are accessing the methods with objects.
When i extend a super-class...i can access the methods of that class
without using an instantiated object like above
This is wrong.
In the first case, you are accessing areaCircle() method on instance c.

When A class extends a class it can access the methods in super class i.e
double areaCircle(double radius)
in your case and when you are writing
System.out.println("Area of circle is : "+areaCircle(3.14));
this statement you are actually using object(this) for accessing this method the only point here is you are not creating this object.
this statement will be interpreted like this
System.out.println("Area of circle is : "+this.areaCircle(3.14));
so you always need object to access a method until it is not static. Because you can access static methods directly with class name.

Related

Cannot pass super keyword as an argument to method in java

Why below program does not work fine?
instead of super in below code if we give this keyword as an argument it will work fine, what is the difference between two codes.
Thanks in advance
class Vehicle
{
int maxSpeed = 120;
}
/* subclass Car extending vehicle */
class Car extends Vehicle
{
int maxSpeed = 180;
void display()
{
test(super);
/* print maxSpeed of base class (vehicle) */
// System.out.println("Maximum Speed: " + super.maxSpeed);
}
public void test(Vehicle obj)
{
System.out.println("Maximum Speed: " + obj.maxSpeed);
}
}
/* Driver program to test */
class Test
{
public static void main(String[] args)
{
Car small = new Car();
small.display();
}
}
There is a misconception on your end. this refences to a real object, therefore you can pass it to any method that allows for an instance of the corresponding class.
But there is no separate super object! super is nothing but a helper mechanism that allows you to access methods or fields of the super class (and it only works within a derived class). It is not intended to deliver a real object refence!
And note: that also doesn't make sense conceptually. You can't really separate the super class properties when looking at a child class due to polymorphism.
It is really simple: you pass this, nothing else. If your code doesn't work then, then that would be a symptom of a bug in your design!
Welcome to StackOverflow.
Your method test receives a instance of a Car, and keyword super it's used to call parent methods, through child class. this keyword returns the instance of the class.
What you're trying to achieve is call super() constructor to pass a instance of a Car to the method, but java states that the the super() call can be used only once in the constructor class as the first statement, to ensure that class will inherit from it's parent, or Object class directly. If you not states it, Java implicitly does it for you.

what is dynamic method resolution

I am currently reading Herbert Schildt "Java the Complete Reference" and there he has used a term "Dynamic method resolution" and has provided a little explanation, but i am not getting the full import of it so asking for help in this forum.
while discussing 'interfaces', what he is saying is, dynamic method resolution helps in resolution of method name at run-time and it is achieved by declaring a interface variable and using it to refer to a class object. i.e
interface i = new object();
now what is so unique about it? you can use a class variable also to refer to the same object like:
class c = new object();
so, what is the use of interface here? and why introduce this new term "dynamic method resolution"??
Second he makes a point by saying: " when we use an interface variable to refer to instance of any class, and when you call a method through these interface variables, the method to be executed is looked up dynamically at run time allowing classes to be created later than the code which calls method on them. The calling code can dispatch through an interface without having to know anything about the callee".
Now, Anything dealing with objects has to be in run-time as objects are created at runtime, Now, I dont understand what he meant by "allowing classes to be created...on them".
Any help will be appreciated.
Here is a little example:
public interface Animal {
public String sound();
}
public class Cat implements Animal {
public String sound() { return "meow"; }
}
public class Dog implements Animal {
public String sound() { return "woof"; }
}
public class Test {
public static void main(String[] args) {
Animal a;
if (args.length > 0)
a = new Cat();
else {
a = new Dog();
}
System.out.println(a.sound()); // prints "MEOW" or "WOOF"
}
}
What is so unique about it? You can use a class variable also to refer to the same object
Yes. But you cannot use a single class variable to refer to an instance that can be an instance of any class that implements the interface.
In Test class, if I declared a to have type Dog or Cat there would be no way to get the code to compile. Without the ability to declare Animal a, I would need to have two distinct variables, and two separate print statements.
This is what dynamic method resolution (aka polymorphism) gives you.
To understand his second point:
public class Test2 {
public static void main(String[] args) {
Animal a = PetShop.buyPet(args);
System.out.println(a.sound()); // prints "MEOW" or "WOOF"
}
}
The Test2 class will work with my Cat and Dog class from above. It will also continue to work without recompilation if in 3 years time I implement a Goldfish class and modify my PetShop class to stock aquatic pets. And indeed, it is even possible to implement the PetShop class so that it doesn't need to be changed or recompiled to support other kinds of pets.
Now, these examples are clearly not practical. However, the Java features that they illustrate are useful in real Java applications. Indeed, a program as simple as a classic "hello world" program relies on dynamic method lookup.
dynamic method resolution means Single method which can be applied to solve multiple problems. Ex: Consider Shape is an interface and has method name draw.
you have Rectangle and Circle classes implements Shape Interface. So when you create instance of Rectangle object and call the draw method will draw the Rectangle shape.. In other case you can instantiate Circle instance and call draw method to draw Circle...
In interface you may assign child object in the parent container.
Ex: Shape p = new Rectangle();
in this case it will create the instance of Rectangle and assign it into Shape p..
but from the Shape p object you can call only the draw method... you can not call other methods in the Rectangle Object since its assigned to parent interface and parent has only draw method.

Java: What's the reason to write Supertype a = new Subtyp()`?

Assume that class B extends from class A.
So what is the advantage of writing something like this:
A myClassA = new B();
What's the difference to:
B myClassA = new B();
This is the concept of programming to interfaces(or supertype)
we use supertype reference so that it can hold any sub type instance
eg: assume we have Class B & C extending A
& some method which accepts A as parameter
void print(A a) {System.out.println(a);}
this method canbe invoked by passing any instance of A or its subtype
Because then if C is a subtype of A, you can say
myClassA = new C();
and your code would (should) still work as intended.
That you may assign an instance of A to myClassA later.
The reason is that if B extends A but all exposed API is defined in A you can treat the object as A without knowing its real type. If future you will probably add yet another implementation C that extends A as well and will probably start using C and B together but you will not have to change the code that uses these objects because it treats them as A.
Program to interface, not an implemenation.
For example,
A myClassA = new B();
Here you can change the implementation, new C() without affecting the existing code since you just exposed the interface.
A myClassA = new C();
or
A myClassA = getClassATypeInstance();
A good example is always that of shapes. Let's say we have two shapes, a circle and a square. Both have different properties, but we can get the area of both.
public abstract class Shape {
public abstract float area();
}
public class Circle extends Shape {
private float radius;
public Circle(float radius) {
this.radius = radius;
}
#Override
public float area() {
return Math.PI * radius * radius;
}
}
public class Square extends Shape {
private float width;
private float height;
public Square (float width, float height) {
this.width = width;
this.height= height;
}
#Override
public float area() {
return width * height;
}
}
Now what this implementation allows, is to calculate the area of all shapes regardless of what types they are. You can for instance have an array of Shapes and iterate over them, calling the area function of each shape and summing the areas up.
One should always put the right information in the right class. Circles and squares both have areas, and so does other shapes to, so it is safe to assume that area is a property of a shape, i.e. circle's have an area because they are shapes.
Putting it lower in the class hierarchy gives your code a healthy level of abstraction. It becomes sort of a "need-to-know-basis"-principle, where you should never have access to more code that you need at the moment. Another rule of thumb is to code so that you always cast from subtype to base, and never the other way around (which is a lot harder than it sounds).
A good example is the Collections API.
Look at the static "min" method of java.util.Collections.
The Parameter type is "Collection" and a lot of classes implement this interface.
You may get the min from a ArrayList (implements List extends Collection) or the values of a HashMap (HashMap.values() returns a private implementation of the Collection interface).
If the java.util.Collections.min() has a ArrayList as parameter type you couldn't use the method to get the minimum value of a HashMap.
Declare your variables and parameters with the basetype if you don't need the additional methods you get through the Subtypes.

Why do I receive a "cannot find symbol" error when compiling this interface method?

I'm using the interface Place:
public interface Place
{
int distance(Place other);
}
But when I try to implement the interface and compile the following code, a "cannot find symbol - variable xcor" error returns.
public class Point implements Place
{
private double xcor, ycor;
public Point (double myX, double myY)
{
xcor = myX;
ycor = myY;
}
public int distance(Place other)
{
double a = Math.sqrt( (other.xcor - xcor) * (other.xcor - xcor) + (other.ycor - ycor) * (other.ycor -ycor) ) + 0.5;
return (int)a;
}
}
Any ideas for what I might be doing wrong? Does it have something to do with the scope of the fields?
The interface Place has no member xcor. Add a method double getXcor() to your interface and implement it in your class. The same applies to ycor. Then you can use these getters in your implementation of the distance method.
public interface Place
{
int distance(Place other);
double getXcor();
double getYcor();
}
It is because the Place interface doesn't expose a symbol named 'xcor'. It only exposes the method 'distance'. so when you have a variable of type Place the compiler doesn't know which underlying type it is. You either have to have Place expose a getter for xcor/ycor etc or downcast the instance of 'Place' to 'Point'. downcasting is usually frowned on when you have multiple implementations of Place, but this is the usual problem with having an interface that overlays implementations that have different underlying properties. Like having a 'Shape' that has 'area()' with implementations of Rectangle and Circle that use different methods of computing area.
A Place does not have an xcor and ycor members, a Point does.
The parameter to the distance method is a Place, not a Point. Only the Point class has a field named xcor.
Several earlier posters mention the problem, which is that distance is being given a Place that has no xcor. I'm going to go a little further and suggest this is a place for generics. It probably makes no sense to define a distance function between arbitrary places. (If it does, then xcor and ycor can be pulled up into an abstract class between Place and Point.)
public interface Place<T> {
int distance (Place<T> other);
}
class Point implements Place<Point> etc.

Java - Abstract class into normal class

public abstract class Figure
{
private int offset;
public Figure()
{
offset = 0;
}
public Figure(int theOffset)
{
offset = theOffset;
}
public void setOffset(int newOffset)
{
offset = newOffset;
}
public int getOffset()
{
return offset;
}
public abstract void drawHere();
/**
* Draws the figure at lineNumber lines down from the
* current line.
*/
public void drawAt(int lineNumber)
{
int count;
for(count = 0; count < lineNumber; count++)
System.out.println();
drawHere();
}
}
In this class, it handles the figure for creating a tree. I am trying to turn it into a normal class by simply giving a body to the abstract method. I noticed that when I remove the abstract tags, it still works perfectly normal. But my question is, if I want to make the class non-abstract, through what means would I go through to do this?
This class is extended upon by 2 other classes and then it has the main class. Do I have to go through and modify those too?
You shouldn't be altering Figure; you should be extending it.
This class is extended upon by 2 other
classes and then it has the main
class. Do I have to go through and
modify those too?
All the more reason to not alter Figure: you'll break the rest of the code.
You should not be modifying anything. Create a new class that extends Figure and override the abstract drawHere() method with the behavior you want.
When you have an abstract class,
abstract class AbstractCar {
float maxSpeed;
Driver whoIsDriving;
AbstractCar(float ms, Driver d) {
maxSpeed = ms;
if(!validateDriver(d)) throw new InvalidDriverException();
whoIsDriving = d;
}
abstract boolean validateDriver(Driver d);
}
You can define the behavior separately for various conditions by extending and defining the abstract methods in question.
class CrappyCar extends AbstractCar {
boolean validateDriver(Driver d) {
return d.hasLicense() && d.hasInsurance();
}
}
class ExpensiveCar extends AbstractCar {
boolean validateDriver(Driver d) {
return d.hasLicense() && d.hasInsurance() && d.hasGoodJobInCaseHeMessesUpMyCar();
}
}
If you want a non-abstract class, then you must not declare it with the abstract modifier (i.e. just public class Figure). There shouldn't be any need to modify any derived classes (so long as they themselves are not abstract).
Technically speaking, in order to make an abstract class non-abstract you have to:
Provide implementation for all abstract methods
Since you now have a valid implementation of everything define, remove all abstract tags
There is no need to modify anything in inheriting classes (assuming they are non-abstract theirselves) because they already provide an implementation of all the abstract methods of their parent & are free to override any method they wish.
Whether or not you should make your class non-abstract is another point of discussion.
You are correct that removing the abstract keywords and implementing the abstract methods makes the class non-abstract.
However, you normally do not want to turn the class itself from abstract to non-abstract. A class is not abstract until you add this keyword, so you (or someone else) apparently had a reason to make sure it's not a normal class, but an abstract one.
If you think about it at a very high level (far from Java), then a "Tree" is something you know how to draw. Similarly, you could imagine a subclass "Circle" for which you know what a drawing shoud look like. For the very generic "Figure", however, you have no idea what it means to draw it.
This is the idea of why the actual drawing is left abstract in your Figure class. Hence, you should not make Figure non-abstract, but instead focus on the classes that extend from it and make those non-abstract, by implementing all abstract methods from Figure. In your Tree class, you know what drawHere should do, so implement it there to print a tree. In another class, like Circle you implement it differently, but it never really makes sense to implement it in Figure, where you have no idea what to draw.
You can declare a method body for drawHere() (presumably empty, since, as #Frank pointed out, you can't really have any idea about how to draw a Figure) and remove the abstract modifiers. Then you will have a concrete class. That means someone could create a new Figure(). This won't be either of the two subclasses you now have, just a Figure.
If such an object (that does nothing when it is called upon to drawHere()) would not be useful (and, in particular, if you would consider it an error to have such an object), then you should keep the class abstract. This reasoning applies even when you can define an implementation for every method.
If a class is made abstract you can give body to all the methodes or none of these but if any class is extending abstract class it must implement all the methode which is only being declared.

Categories

Resources