Can I use the contains method on every object? - java

Can the contains method be used on instances of classes I've written myself?
I've created a class named Ana and in another class, I've created two instance of it called cookie and maccaroni. This is one of them:
Ana cookie = new Ana(cc.c, 20, 450);
At some point I am trying to invoke
if (maccaroni.contains(cookie.image(), cookie.xi(), cookie.yi())
{
return true;
}
but Netbeans underlined it to indicate a mistake. When I hovered over it, it said:
no suitable method found for contains(Image,int,int)
method Component.contains(int,int) is not applicable
(actual and formal argument lists differ in length)
method Component.contains(Point) is not applicable
(actual and formal argument lists differ in length)
method JComponent.contains(int,int) is not applicable
(actual and formal argument lists differ in length)
Why the following code is regarded as a mistake by Netbeans?
This is the class I'm referring to.
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JComponent;
public class Ana extends JComponent
{
public static Image p;
public static int xx;
public static int yy;
public Ana(Image io, int x, int y)
{
p = io;
xx = x;
yy = y;
repaint();
}
#Override
public void paint(Graphics g)
{
g.drawImage(p, xx, yy, null);
}
public Image image()
{
return p;
}
public int xi()
{
return xx;
}
public int yi()
{
return yy;
}
}

There is no contains() method defined in Ana. There is a contains() method defined in JComponent. It takes two integers. You're trying to invoke it with an image and two integers. You can probably get what you need by writing it like this:
if (maccaroni.contains(cookie.xi(), cookie.yi())
{
return true;
}
So the kind of error in this code is: it's a compile error. NetBeans isn't just underlining it, there is a message somewhere on your screen telling you what is wrong. You may have to mouse over the underline or look in a different section of the screen--I don't use NetBeans on a regular basis so I don't recall exactly--but I assure you the message is there.
And no, you can't invoke contains() on any object, only on objects which classes define a contains() method (with proper parameters), or that inherit such a method from one of their supertypes (from an ancestor class or interface they implement).
Methods which all objects could use are those inherited from java.lang.Object class, since all classes explicitly or implicitly extend it (parent of parent of parent... finally will need to extend the Object class).
But there is no contains(Image, int, int) method defined on java.lang.Object. The only contains() method available to instances of the Ana class is the one inherited from JComponent which is contains(int, int). As you see it accepts two int arguments, which prevents you from using it with the additional Image argument.
By the way, as #PShemo has noted, your fields p, xx and yy should likely be private and most definitely not static.

Related

Difference between returning a parent type or child type

I was wondering (and pardon if this is a repeat question, but I could not find information specifically regarding my question) what the difference between defining a method as returning a parent type or child type. Here is my specific scenario:
Imagine the following classes and interface:
public interface Color{
public int getRedVal();
public int getGreenVal();
public int getBlueVal();
}
public class RGBColor implements Color{
public int getRedVal() {...}
public int getGreenVal() {...}
public int getBlueVal() {...}
}
public class HSVColor implements Color{
public int getRedVal() {...}
public int getGreenVal() {...}
public int getBlueVal() {...}
}
Now, if I were to include a method called getRGB(), what would be the difference between:
public Color getRGB() {return new RGBColor();}
and
public RGBColor getRGB() {return new RGBColor();}
I can't seem to find documentation regarding this, and I'm sure it's a simple answer. Either way, thanks in advance for the answer.
public Color getRGB() { return new RGBColor(); }
Up-casting is here (casting to a supertype). You are working on more abstract level not thinking about implementation (what is good) and can use only parent's methods.
public RGBColor getRGB() { return new RGBColor(); }
You and your architecture are tightly bound to the implementation (RGBColor), but can use specific methods defined in this subclass.
I would prefer the first option rather than the second one.
First, you should make your factory methods static.
Second, the difference between the two methods is the declared return type. If you used the first of the two definitions, a programmer would write:
Color c = getRGB(); // this is legal
They could not write:
RGBColor c = getRGB(); // This is illegal
There's not much difference if you've coded to your interface correctly. However, the difference is simply the reference type.
Suppose RGBColor had an additional public method:
public int[] getRGBFormatVals() //I dunno; I made it up!
You would not be able to invoke this method on an instance you obtained from a return type Color, but you could if you used return type RGBColor. To restate my previous point, this is unlikely to occur if you've coded to your interface properly.
Since your method is called getRGB, I would recommend returning an RGBColor, because that's all that should return from a method with such a name. You could just as easily assign it to a Color reference though to have the same effect and see the result.

Passing parameter as Wrapper class and overriding

Please clarify my doubt on overriding, When I am calling a method which is not overrided, the method that is being called is form parent class, please give brief explanation on this, The example is like this
public class A {
public void test(int x){
System.out.println("Haiiiiiii");
}
}
public class B extends A{
public void test(Integer x){
System.out.println("hiii Im b's method");
}
}
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
B a=new B();
a.test(2);
}
}
I'm calling b's method but in B class the method takes wrapper class as parameter.
There are 2 methods. One accept int and other accept Integer type. So when you call test() method first it try to find a suitable method without doing any autoboxing. In that case it can find the parent class test() method which accept an int. Therefore java will execute that.
If in case it wouldn't exist then it will try to autobox your parameter and check if there a suitable method. In that case your child class method will get execute.
Edited
Java will always pick the most specific method for a type. Casting/autoboxing/unboxing only when it has to.
If you wanna call child class method you can try
a.test(new Integer(2));
In this case overriding not happen. since overloading when you call it will call the method accept input argument as int.
The compile lets you auto-box and unbox between primitives and wrappers but this doesn't make one a sub-class of the other. int and Integer are two different types hence both of them when used in the method act as two different method (as in your case)
Refer below link for a much clearer explanation
int does not override Integer in Java

Which of the following methods will be legal in the subclass?

I am confused about how to create methods in a subclass. I am hitting my head against a brick wall with this and not even sure how to word the question.
import java.io.*;
public class A {
public double method1(double x, double y) { return 1.0; }
}
class B extends A {
//subclass method to be placed after this line
}
public double method1(double x, double y) { ... }
public int method1(double x, double y) { ... }
public double method1(int x, int y) { .... }
public int method1(double x, double y, double z) { ... }
Which of the following methods will be legal in the subclass and why?
Overrides method1 with new functionality.
Illegal because it has the same parameter signature but a different return type.
3,4. legal but are really separate methods.
Just consider the argument types to be part of the method name:
Only if the name plus the argument types fully match, you override the same method with new functionality. In this case, the return type must match (starting with Java 1.5, the return type may be specialized in subclasses, see https://blogs.oracle.com/sundararajan/entry/covariant_return_types_in_java)
In other cases, the added methods are just separate methods with the same name. Java statically picks the right one for each invocation at compile time based on the provided argument types. If arguments are compatible and the names are the same for multiple methods, it picks the closest match.
If you put the following methods in class, as per my understanding, this should happen:
public double method1(double x, double y) { ... }
This is overridden method, which means you overriding the behavior of method1 in your subclass, which is perfectly legal.
public int method1(double x, double y) { ... }
Compilation error: This is a try to do method overloading but not in a legal way. Method overloading allows to have same method name but different type/number of arguments. Method overloading is done with different parameter list but NOT by using a different return type.
public double method1(int x, int y) { .... }
This one is a legal overloaded method
public int method1(double x, double y, double z) { ... }
Again a legal overloaded method
Overrides the method in A and is legal
Is illegal because returntype is different and not a specialisation of the returntype of the method in A
Is an overloaded method because the argument types are different
Is an overloaded method because there are more parameters
See also http://en.wikipedia.org/wiki/Function_overloading and http://en.wikipedia.org/wiki/Method_overriding
Legal overriding
Not Legal overriding because return type should be covarient or same
legal overloading
legal overloading
overriding rules :- * parameter must same
return type must same or it should be covarient
exception if it is checked it should be sub class of that overridden method
access modifier should be same or less restricted
overloading rules :- * parameter must different
return type can be same
access modifier can be same
Read Katherine Sierra, Bert Bates (SCJP Book) for full rules or Java doc

Compiler interpretation of overriding vs overloading

Forgive me if this question is primarily opinion based, but I have the feeling that it is not and there is a good reason for the choice. So, here's an example. Sorry, it's really long, but super simple:
Interface:
public interface Shape
{
double area ();
}
Implementing class 1:
import static java.lang.Math.PI;
public class Circle implements Shape
{
private double radius;
public Circle(double radius)
{
this.radius = radius;
}
public double area()
{
return PI*radius*radius;
}
}
Implementing class 2:
public class Square implements Shape
{
private double size;
public Square(double sideLength)
{
size = sideLength;
}
public double area()
{
return size*size;
}
}
Driver:
Shape[] shapes = new Shape[]{new Circle (5.3), new Square (2.4)};
System.out.println(shapes[0].area()); //prints 88.247...
System.out.println(shapes[1].area()); //prints 5.76
This works since .area() is overridden by Circle and Square. Now, here's where my question truly begins. Let's say that the driver has these methods:
public static void whatIs(Shape s)
{
System.out.println("Shape");
}
public static void whatIs(Circle s)
{
System.out.println("Circle");
}
public static void whatIs(Square s)
{
System.out.println("Square");
}
If we call:
whatIs(shapes[0]); //prints "Shape"
whatIs(shapes[1]); //prints "Shape"
This happens because Java interprets the objects as Shapes and not Circle and Square. Of course we can get the desired results through:
if (shapes[0] instanceof Circle)
{
whatIs((Circle) shapes[0]); //prints "Circle"
}
if (shapes[1] instanceof Square)
{
whatIs((Square) shapes[1]); //prints "Square"
}
Now that we have a background my question is:
What reasons contributed to the compiler/language design such that whatIs(shapes[0]); will print "Shape?" As in, why can the Java compiler accurately distinguish between overridden methods for related objects, but not overloaded methods? More specifically, if the only methods that the driver has access to are:
public static void whatIs(Circle s)
{
System.out.println("Circle");
}
public static void whatIs(Square s)
{
System.out.println("Square");
}
and we attempt to call,
whatIs(shapes[0]);
whatIs(shapes[1]);
we will get two errors (one for Square and one for Circle) indicating that:
method Driver.whatIs(Square) is not applicable
actual argument Shape cannot be converted to Square by method invocation conversion
So, again, now that we've gotten to the nitty-gritty, why can Java not handle a situation like this? As in, is this done due to efficiency concerns, is it just not possible due to the some design decisions, is this a bad practice for some reason, etc?
Why can the Java compiler accurately distinguish between overridden methods for related objects, but not overloaded methods?
It can't.
It checks strictly by the type it can see & guarantee. If your code is shapes[0].area() it will check that Shape has an area method and will compile it to "call area() on that object". The concrete Object that exists at runtime is now guaranteed to have that method. Which version from which class is actually used is dynamically resolved at runtime.
Calling overloaded methods works the same. Compiler sees a Shape and compiles that into "call whatis() in the basic Shape version". If you wanted to change that (and even allow having no basic Shape version) you would need to be able to determine the type at compile time.
But it is AFAIK impossible to create a compiler that can determine the type that an object will have at runtime at that point. Think for example:
final Shape[] shapes = new Shape[] { new Circle(5.3), new Square(2.4) };
new Thread() {
public void run() {
shapes[0] = new Square(1.5);
}
}.start();
whatIs(shapes[0]);
You must execute that code to find out.
The compiler could auto generate code like
if (shapes[0] instanceof Circle)
{
whatIs((Circle) shapes[0]); //prints "Circle"
}
for you to achieve dynamic method invocation at runtime but it does not. I don't know the reason but it would be neat to have sometimes. Although instanceof is often a sign for bad class design - you should not look from the outside for differences, let the class behave differently so the outside does not need to know.
Java, with object-oriented features, supports polymorphism, so calling area will call the area method of the specific instance, whatever it is. This is determined at runtime.
However, this polymorphism is not supported with overloaded methods. The Java Language Specification, Section 8.4.9 covers this:
When a method is invoked (§15.12), the number of actual arguments (and
any explicit type arguments) and the compile-time types of the
arguments are used, at compile time, to determine the signature of the
method that will be invoked (§15.12.2). If the method that is to be
invoked is an instance method, the actual method to be invoked will be
determined at run time, using dynamic method lookup (§15.12.4).
That is, with overloaded methods, the method is chosen at compile time, using the compile time types of the variables, not at runtime like with polymorphism.
The dispatch to one of the whatIsmethods is decided by the compiler at compile time. The call to one of the areamethods is decided at runtime, based on the actual class of the object that is referenced.
Q: Why can the Java compiler accurately distinguish between overridden methods for related objects, but not overloaded methods ... why can Java not handle a situation like this?
A: You've got the question backwards.
Java ALLOWS you to distinguish between "overloading" and "overriding".
It doesn't try to second-guess what you mean, it gives you a choice to use one or the other.
Well, as a stupid answer, you could get the whatIs function to work fine THIS way (without any type checking)
class Shape{
public abstract String whatIs();
}
class Square{
public String whatIs(){ return "Square"; }
}
class Circle{
public String whatIs(){ return "Circle"; }
}
And then call them like this
Shape square = new Square();
Shape circle = new Circle();
System.out.println(square.whatIs()) //prints 'square'
System.out.println(circle.whatIs()) //prints 'circle
Not at all the answer to the question you asked... But I couldn't resist.

Is this Overloading, methods with same name in different classes and different signature?

If I have the following code in Java:
class A {
public int add(int a , int b) {
return (a+b);
}
}
class B extends A {
public float add(float a , float b) {
return (a+b);
}
In this particular case the sub-class isn't exactly overriding the base class's add function as they have different signatures and the concept of overloading occurs only if they are in the same scope. So, is the function add(float , float) in the sub-class B treated as an entirely new function and the concept of overloading and overriding is not applicable to it? And does it use 'Static binding' or 'Dynamic Binding'?
Method add in class b is an overload of add in class a. Not an override. An override would just be a different implementation of the original add method.
In brief, yes. To override, you need to replicate the complete method signature, which includes the method name, parameters and return types. From the tutorial
An instance method in a subclass with the same signature (name, plus
the number and the type of its parameters) and return type as an
instance method in the superclass overrides the superclass's method.
You might want to consider the #Override annotation, which will trigger a compiler error if you don't successfully overrride a method.
In this particular instance, it perhaps looks like you don't need overriding so much as some solution including generics. So you could instantiate a class a<Integer> and a similar class a<Float>
In that case you are not overriding the method, since the signatures are different.
But there is overloading in class b, since you have two methods with the same name but different parameters (one if class a, and the other one in class b)
Hope it helps.
There can be a method that is not overridden but overloaded in the subclass. Here the subclass has two add() methods. The version which accepts int arguments(not overridden), and the overloaded method add() which accepts float arguments.
I think in this particular case neither overloading nor overriding occurs, because return type must be same in case overloading and overriding, so neither static binding nor dynamic binding happens in this case.
method overloading is not possible in case of different return type, because compiler can't figure that which method he need to call.
I know it's late answer but i think it's important question need to be answered for beginners.
One key point in overloading is it works in inheritance.
Next is either it's Static binding or Dynamic binding.
It is Static Binding So, why?
Static Binding
Static binding in Java occurs during Compile time.
private, final and static methods and variables uses static binding and bonded by compiler.
Static binding uses Type (class in Java) information for binding.
Dynamic Binding
Dynamic binding occurs during Runtime.
Dynamic methods bonded during runtime based upon runtime object.
Dynamic binding uses Object to resolve binding.
But the important part is here
Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime.
Java compiler determines correct version of the overloaded method to be executed at compile time based upon the type of argument used to call the method and parameters of the overloaded methods of both these classes receive the values of arguments used in call and executes the overloaded method.
B a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);
So if you will create reference of type B then it will search for proper argument type
and for above code it will execute both methods.
A a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);
but for above code it will give compile time error for float arguments.
Hope it clears all doubts.
First things first
Is it method overriding ?
No , since to override a method you need to replicate the complete method signature as pointed out in Brian Agnew's answer and as I explain below.
Is it overloading ?
Yes , Method "add" has an overloaded implementation in Class B.
Consider the following code:
class C{
public static void main(String args[]){
B a = new B();
a.add(2 , 3);
a.add(2.0 , 3.0);
}
}
class A {
public int add(int a , int b) {
System.out.print("INT ");
return a + b;
}
}
class B extends A {
public double add(double a , double b) {
System.out.print("Double ");
return a + b;
}
}
OUTPUT : INT Double
So , the method in Class B in your code overloads the add method that it inherits from its parent
Does it use Static Binding or Dynamic Binding ?
This is what makes me conclude that OP is confused.It is static binding because it is a overloaded function. The only way to think of dynamic binding would have been in below scenario
class C{
public static void main(String args[]){
A a = new B();
a.add(2.0 , 3.0);
}
}
class A {
public int add(int a , int b) {
System.out.println("A : INT");
return a + b;
}
}
class B extends A {
public int add(int a , int b) {
System.out.println("B : INT");
return a + b;
}
public double add(double a , double b) {
System.out.println("Double");
return a + b;
}
}
Output : B : INT
Here , the parent class A has a contract that says , "I have an add behaviour for ints" . class B inherits this add behaviour and makes it more specific and at the same time also provides a new behaviour where it can add doubles.
But class A has "no knowledge of this behaviour".
So an object of class A "cannot" add doubles. To do that you need a more specific type of A object i.e. a B object.
The method add() in class A is also available to class B by inheritance, therefore the method is overloaded in class by changing the data type from int, int to float, float.
The concept of Overloading comes in play if and only if the functions are in the same scope or class.
cz if this is the case of method overloading then for same method signature or same argument type the compiler gets confuse and must give compile time error .
but in the above program in class B if you pass the same argument in same order then according to overloading it must give error but it is not happening u can check it i already have.
It is the case of inheritance where through object reference if you call any method then the compiler will check it in child class ,if its not there then it will look into parent class that the above program is all about.
hope this is helpfull.

Categories

Resources