I don't know how simple this would be or if it is possible but I can't seem to find any information on it. For a method is there a way to set multiple parameters.
For example in this public void it is required you call a component and and string when you call the method in your java file.
public void testMethod(Component c, String s)
{
//Do Something
}
Is there way to say public void testMethod(Component c, String d) or public void testMethod(Component c, int i) and when the method is called either could be specified?
It's called method overloading. Just create them as separate methods and the compiler will (usually) infer the right one based on your input values.
Yes this is possible and is an inportant concept. This particular technique is called function overloading. Suppose you declare 2 functions like:
public void testMethod(Component c, String d) {} //function 1
and
public void testMethod(Component c, int d) {} //function 2
You can then call these functions from main as:
testMethod(c,"Hello") //calls function 1
testMethod(c,1) //calls function 2
It is called "method overloading". Any two methods can have the same name, as long as the parameters are different. For example:
public void doStuff(String string, int integer) {}
public void doStuff(Object object, float flt) {}
This also applies for constructors:
public Thing(String name, int id) {}
public Thing(Object object, long id) {}
However, take the following two methods for example:
public void doStuff(String string) {}
public void doStuff(Object object) {}
Now, call the method doStuff(null). The compiler cannot infer which one to use; in which case, you will get a compilation error. This also occurs in constructors (just to get it out of the way, constructors are almost the same as methods).
Simply stated, you can.
public void testFunction(Component c, String s) {
// Handle on a string
}
public void testFunction(Component c, int i) {
// Handle on integer
}
This is called method overloading. Whichever type is passed will cause your function call to use the appropriate method. The order of the parameters is still important.
Related
I remember on my previous web development job that they have something like this:
sampleClassBean.java:
public class sampleClassBean
{
public String doSomeStrings(String a, String b){}
public Int doSomeInt(Integer i, integer j){}
public Boolean doSomeBoolean(Boolean result){}
}
and then there's sampleClassBeanImpl
public class sampleClassBeanImpl
{
public String doSomeStrings(String a, String b)
{
//do some process
return "";
}
public Integer doSomeInt(Integer i, Integer j)
{
//do some process
return 0;
}
public Boolean doSomeBoolean(Boolean result)
{
//do some process
return false;
}
}
For what I understand is that, there's 2 class, 1st class that declare methods, now 2nd class's methods will depend on what is declared on the 1st class. If the 2nd class create a method that is not declared in 1st class there will be an error. Hope you understand what i'm saying.
What I need to know is what exactly that? What do you call that process? How to do that? What are the benefits of doing that? Is it a good programming practice?
Yes it is good practice, you are talking about interfaces:
Java includes a concept called interfaces. A Java interface is a bit like a class, except a Java interface can only contain method signatures and fields. An Java interface cannot contain an implementation of the methods, only the signature (name, parameters and exceptions) of the method.
The interface:
public interface SampleClassBean {
public String doSomeStrings(String a, String b);
public int doSomeInt(int i, int j);
public Boolean doSomeBoolean(Boolean result);
}
And the implementation:
public class SampleClassBeanImpl implements SampleClassBean {
#Override
public String doSomeStrings(String a, String b) {
return null;
}
#Override
public int doSomeInt(int i, int j) {
return 0;
}
#Override
public Boolean doSomeBoolean(Boolean result) {
return null;
}
}
Interfaces are really useful because unlike other languages Java doesn't support multiple inheritance but you can implement all the interfaces you wish!
Have a read of this it'll help you understand interfaces and when to implement them.
why it is printing Integer?
At the time of compilation, the method call bound to class A's method.
I hope in B I am not overriding. creating a other method means method overloading with different classes.
but what is happening at run time?
class A{
void method(Integer i)
{
System.out.println("Integer");
}
}
class B extends A
{
void method(int i)
{
System.out.println("Int");
}
}
public class Puzzle{
public static void main(String ar[]){
A a = new B();
a.method(20);
}
}
B has two different methods called method: one declared by A, which is method(Integer), and one declared by B, which is method(int).
Since your variable a is of type A, a call to a.method() must refer to a method provided by class A, which is method(Integer).
Your methods don't share the same signature.
void method(int i) is not equal to void method(Integer i) - the first one uses primitive type. Second one uses Object Integer.
If you change method in A to method(int i) you can then override the method of A, so in your subclass:
#Override
void method(int i)
{
System.out.println("Int");
}
B doesn't override the method called "method" because it is not the same type of parameter of your method in A (Integer).
int is a primitive type while Integer is a class.
B method should be :
#Override
void method(Integer i)
{
System.out.println("Int");
}
The annotation #Override is here to tell the class should override a method. It is a good practice but not necessary (I would work without it). If you put it with your current code you would have an error because method doesn't override any method.
I hope it will help you.
This is exactly what #Override annotation is for - add #Override when you think you're overriding and the compiler will tell you if you're wrong in thinking so.
If you add #Override to the B's method(int i), the compiler will give you an error telling you that you're not in fact overriding it, because the signatures differ - namely the method has different parameter type that's not a superclass of parent's parameter type.
The signatures of the method of A and that of B are not the same. The method in A takes an object integer (Integer) as parameter while that of B takes a primitive integer (int) as parameter. So you are not really overriding the method of A in B. To do so, change the signature of the method B to be like that of A.
class A{
void method(Integer i){
System.out.println("Integer");
}
}
class B extends A{
#Override
void method(Integer i){
System.out.println("Int");
}
}
public class Puzzle{
public static void main(String[] args){
A a = new B();
a.method(20);
}
}
Your reference is of type A - it does not recognize methods declared in type B in compile time, even though the may exist in runtime. The int literal 20 is then autoboxed to a java.lang.Integer, and method(Integer) is called.
If you were to declare the reference as B, the method(int) would be a better fit to your argument, and would be have been called.
I'm new with Java and I'm having trouble understanding the constructor issue,
I have looked at many tutorials and still I'm having difficult to understand why we use constructors, anyway, my specific question is :
Correct me if I'm wrong, if i want to add in my class more than one constructor, I'll write the first one and the second will be int type (inside the brackets).
is it because the constructors have to be with the same name as the class and we need to distinguish between them ?
what if I want to add a third constructor ? Can it also be int type ?
a) is it because the constructors have to be with the same name as the
class and we need to distinguish between them ?
Yes constructors are always the name of the class without any return type, and in order to distinguish between them, you can have different parameters.
b) what if i want to add a third constructor ? it can be also int type
?
Yes, you can add any no. of overloaded constructors but those all should be different in no. and/or type of parameters.
Like :-
public User() // default constructor
{
}
public User(int age) // overloaded constructor with int
{
}
public User(String name) // // overloaded constructor with String
{
}
public User(String name, int age) // // overloaded constructor with String and int
{
}
Yes a constructor has the same name as the Class.
As long as the constructors have different signatures you can have as many as you want. The signature is what distinguishes one constructor from another...
public MyClass()
{
}
public MyClass(int a)
{
}
public MyClass(int a, int b)
{
}
public MyClass(String a)
{
}
public MyClass(int a, String b)
{
}
Those are all different because they have different signatures.
Actually, if you want to have 10000 constructor, you can as long a signature are differents.
public class People {
public People(String name, int age) {
...
}
public People(String name) {
...
}
}
You can construct your object in a different way.
You can see an example by yourself looking at : the java String class wich has a plenty of constructors.
And yes, all constructors have the same name of his class.
But this will not works :
public class People {
public People(String name, int age) {
...
}
public People(String name, int numberOfLegs) {
...
}
}
Since you have two constructors with the same signature
The constructors purpouse is to contain the code to inizialize the object. Usually, the initialization is done using constructor parameters. You can have different constructors with different parameters list, as needed by your context. It is a good pratice to do constructor chaining, that is calling a base constructor from others.
Adding to the #brso05 answer,
This is also one of the ways:
public MyClass( int a)
{
}
public MyClass( int a, int b)
{
}
public MyClass( int a, String b)
{
}
And So on..It is the arguments which make difference, rest remains the same!
Please see this Java Class
class Demo
{
public static void a(String s)
{
System.out.println("string called");
}
public static void a(Object a)
{
System.out.println("Object called");
}
public static void main(String...asrgs)
{
a(null);
}
}
The output of this code is "string called" but I am not able to understand that how compiler is able to resolve between Object and String.
Moreover, examine this code fragment
class Demo
{
public static void a(String s)
{
System.out.println("string called");
}
public static void a(Integer n)
{
System.out.println("number called");
}
public static void a(Object a)
{
System.out.println("Object called");
}
public static void main(String...asrgs)
{
a(null);
}
}
Here we get a compile time error related to ambiguous call (which is quite obvious).
Any good explanations for this ?
The answer lies in §15.12.2 of the JLS:
The second step searches the type determined in the previous step for member methods. This step uses the name of the method and the argument expressions to locate methods that are both accessible and applicable, that is, declarations that can be correctly invoked on the given arguments.
There may be more than one such method, in which case the most specific one is chosen. The descriptor (signature plus return type) of the most specific method is the one used at run time to perform the method dispatch.
(my emphasis)
...and §15.12.2.5, which the section above refers to, which has the full details of specificity rules, but also this handy summary:
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error.
In your first example, a(String) is more specific than a(Object), so the compiler knows which one to use and is happy. In your second example, both a(String) and a(Integer) are more specific than a(Object), but either is applicable to null and they're in separate lineages (String is String > Object, Integer is Integer > Number > Object), creating the ambiguity the compiler complains about.
If they were in the same lineage, there'd be no ambiguity, because there'd be a single applicable most specific option. For example:
class Base {
}
class Child extends Base {
}
class GrandChild extends Child {
}
public class Example {
public static final void main(String[] args) {
a(null);
}
public static void a(Base b) {
System.out.println("Base");
}
public static void a(Child b) {
System.out.println("Child");
}
public static void a(GrandChild b) {
System.out.println("GrandChild");
}
}
That prints "GrandChild", because while both a(Child) and a(GrandChild) are more specific than a(Object), a(GrandChild) is more specific than a(Child).
I'm trying to write an event engine in Java using the newly added lambdas. I would very much like it if the following code would work:
public class Test
{
public Test()
{
EventEngine.listen(EventType.THIS, self::thisEventCallback);
EventEngine.listen(EventType.THAT, self::thatEventCallback);
EventEngine.listen(EventType.OTHER, (other) -> other.doX());
}
private void thisEventCallback()
{
// do whatever here
}
private boolean thatEventCallback(SomeObject parameter)
{
return parameter.someCheckOrWhatever();
}
}
As far as I understand, I would have to define a generic empty interface, for example, public interface Listener {// nothing here}, and extend it via various other interfaces for each event type so I can specify different parameters and return types where necassary.
Obviously, that would require casting the callbacks to the specific interface inside the EventEngine's trigger method(s), but I have no problem with that.
However, before that I need to find out how to reference these private methods I have defined to the EventDispatcher.listen method. self::thisEventCallback doesn't work. Is there even a way to do this in Java 8 or is it only possible in Scala?
If not, then what would you suggest as a replacement that does not involve creating a new object for every listener/callback?
EventEngine.listen(EventType.THIS, this::thisEventCallback);
EventEngine.listen(EventType.THAT, this::thatEventCallback);
EventEngine.listen(EventType.OTHER, (other) -> other.doX());
So this instead of self.
And you need functional interfaces with one abstract method having the same signature as the callback.
public interface THISInterface {
public void thisEventCallback();
}
public interface THATInterface {
public boolean thatEventCallback(SomeObject parameter)
}
class EventEngine {
public void listen(Type t, THISInterfcace thisCallback) {
thisCallback.thisEventCallback();
}
public void listen(Type t, THATInterfcace thatCallback) {
boolean ok = thatCallback.thatEventCallback();
}
...
}
However there are already many functional interfaces predefined, which you should need to learn. For instance here, one would not need own interfaces.
class EventEngine {
public void listen(Type t, Consumer<Void> thisCallback) {
thisCallback.accept();
}
public void listen(Type t, Predicate<Void> thatCallback) {
boolean ok = thatCallback.test();
}
Whether the above is correct, I am not sure (at the moment deep in java 6 - sigh).
Instead of creating sub-interfaces adding new methods to a base interface you can define a conventional listener interface (like, say MouseListener) having multiple call-back methods and create sub-interfaces overriding all but one method with empty default methods for the sole purpose of allowing lambda implementations of the remaining single abstract method. They replace what classes like MouseAdapter did for previous Java versions (when using anonymous inner classes):
interface AllPurposeListener {// the only one our engine uses internally
void caseOne(int arg);
void caseTwo(String arg);
}
interface CaseOneListener extends AllPurposeListener {
#Override public default void caseTwo(String arg) {}
}
interface CaseTwoListener extends AllPurposeListener {
#Override public default void caseOne(int arg){}
}
// Of course, I over-simplify the engine’s listener registry here
AllPurposeListener listener;
public void listen(AllPurposeListener l) {
listener=l;
}
public void listen(CaseOneListener l) {
listener=l;
}
public void listen(CaseTwoListener l) {
listener=l;
}
private void foo(int i) { }
private void bar(String s) { }
void doRegistration() {
listen(this::foo);// register for case one
listen(this::bar);// register for case two
listen(new AllPurposeListener() { // for all cases
public void caseOne(int arg) {
}
public void caseTwo(String arg) {
}
});
}