The following code is a testing program. Why i can't use A(int a), in this program?
public class A {
int a;
void meth(int b) {
a+=b;
}
A(int a) {
this.a=a;
}
}
class B extends A {
int a;
void meh2(int b) {
a+=b;
}
}
why can't pass parameter to constructor? What the reasons? Netbeans error message:
constructor A in class tma1.A cannot be applied to given types;
required: int
found: no arguments
reason: actual and formal argument lists differ in length
In the class B, you need constructor. If you mean that you can't call A from B, that's just because you're extending class A, so you need to use super, which refer to the superclass. For example B could be:
class B extends A {
B(int a) {
//You can put additional code here
// This calls the constructor of A
super(a);
//You can put additional code here
}
int a;
void meh2(int b) {
a+=b;
}
}
Otherwise you need to assign something to the variable a in class B, if you're not omitting something in code
Unless a class has a defined constructor, it automatically has a no-arg constructor that merely calls super().
The complaint from your compiler seems to be: "your no-arg constructor [that you can't see] is calling up to a parent no-arg constructor that doesn't exist."
Class A doesn't have a no-arg constructor because there's another one defined (so java doesn't have to create one).
Related
I have a (non abstract) generic base class A<L,M>, an abstract generic sub class B<K, L, M> extends A<L,M> and a (non abstract) class C extends B<Integer, Integer, Void> :
public class A<L,M> { }
public abstract class B<K, L, M> extends A<L,M> { }
public class C extends B<Integer, Integer, Void> { }
I have a utils class that has a few methods, two are relevant here:
public static <K, L, M> void doSomething(B<K, L, M> b) {...}
public static <L, M> void doSomething(A<L, M> a) {...}
To be clear, both methods have the same name.
If I call doSomething(c); (where C c) it goes as expected to the 1st method.
My issue is with the following code (at another class that uses the utils):
private void doSomethingMoreComplex(A a) { // a is actually C
Utils.doSomething(a);
}
So here a is actually C but it goes to the second method, I am not sure if I made a mistake in the code or this is actually the expected behavior.
This is the expected behavior. The runtime type of a is inconsequential, as this method resolution is done in compile time. Since doSomething(B) cannot be applied to an argument of type A, the method is resolved to doSomething(A).
You could handle this yourself by explicitly downcasting a:
private void doSomethingMoreComplex(A a) { // a is actually C
if (a instanceof B) {
Utils.doSomething((B) a);
} else {
Utils.doSomething(a);
}
}
... but, well, in a word - yuck.
The more idiomatic way to address this would be to have doSomething as a method of A and override (not overload) it in B.
or this is actually the expected behavior.
Yes, it's the expected behavior.
The compiler chooses which method is run, and it doesn't know that it is a B (because you've said it's an A). So it doesn't know if the first overload is safe to invoke, but it knows the second overload is.
I have the following classes:
Base class
public abstract class ArrayManipulation {
public <T> T[] largestSubArray(T[] a){
(((CharacterArrayManipulation)this).compare(a[0],a[1]);
return a;
}
abstract <T> boolean compare(T a,T b);
}
Sub class
public class CharacterArrayManipulation extends ArrayManipulation<Character> {
public Character[] largestSubArray(Character[] input){
super.largestSubArray(input));
}
//This is not seen as overriding
protected boolean compare(Character a, Character b){
return a==b;
}
}
I want to override the compare function in the sub-class CharacterArrayManipulation. When I try to do that, I get
CharacterArrayManipulation must either be declared abstract or implement abstract method compare(T,T) in ArrayManipulation
EDIT
I changed it to the following after the comments, it still seems to give the same error:
Base class
public abstract class ArrayManipulation<T> {
public T[] largestSubArray(T[] a){
this.compare(a[0],a[1]);
return a;
}
abstract boolean compare(T a,T b);
}
Sub class
public class CharacterArrayManipulation extends ArrayManipulation<Character> {
public Character[] largestSubArray(Character[] input){
super.largestSubArray(input));
}
//This is not seen as overriding
#Override
boolean compare(Character a, Character b){
return a==b;
}
}
First of all, your super class should not have any knowledge of its sub classes, and so the implementation of ArrayManipulation.largestSubArray() should be left empty and abstract, or non-empty with a body that does not do any casting to sub classes (the casting is unnecessary as all sub classes of ArrayManipulation will have an overridden version of compare(), not just CharacterArrayManipulation).
Your super class isn't generic, as you haven't added the T generic to the class header.
public abstract class ArrayManipulation<T> { ... }
You should then remove the generic declaration from the largestSubArray() method and the compare() method.
public T[] largestSubArray(T[] a){ ... }
boolean compare(T a, T b);
You can't use an access modifier in the overriding version that is different to the overridden version.
// Note the lack of `protected`
boolean compare(Character a, Character b){ ... }
Side-note: You should use the #Override annotation when overriding methods. It will give you more applicable error messages and explicitly says that you are attempting to override a method.
When you declare a method with a generic placeholder you get a generic method. Even when you use the same name for the placeholder as in the surrounding class this is not the same.
The problem is:
abstract <T> boolean compare(T a,T b);
This T is different (try, it will give the same error when renamed to U).
When understanding your code right, simply removing the declaration of this additional generic variable will solve your problem:
abstract boolean compare(T a,T b);
now the generic placeholder of the class is used which is what you expected I think.
in recent project, I have to write a lot of functions in same class with similar first few parameters like below:
doA(string t, int x);
doB(string t, int x, object y);
....
doN(string t, int x, object... ns);
Can we have a generic function like doA() function, so that any function which extend doA function must have 2 parameters string t, int x? as doB extends doA(object y) instead of doB() above?
Yes, if you do something like that:
class A{
// not accessible by child
private void doA(int a){
...
}
// accessible by child and B can be null
public void doA(int a, Long B){
doA(a);
}
}
class B extends A{
#override
public void doA(int a, Long b){
...
}
}
I hope I got your question right.
If you need to access A's private method you can change its accessibility with reflections.
You cant extend a method signature. In Java extends is allowed for class and interface; not for method. To share common parameter among multiple methods you could changed them to instance variable.
e.g.
class YourClass {
String t;
int x;
}
I am seeing the following kind of code repeatedly in Mapreduce programs. This is just a snippet of code taken out. The entire code is available here
what does the super call in the constructor do? Does it call the constructor of IntPair.class? why is such a call necessary.
public static class KeyComparator extends WritableComparator {
protected KeyComparator() {
super(IntPair.class, true);
}
#Override
public int compare(WritableComparable w1, WritableComparable w2) {
IntPair ip1 = (IntPair) w1;
IntPair ip2 = (IntPair) w2;
int cmp = IntPair.compare(ip1.getFirst(), ip2.getFirst());
if (cmp != 0) {
return cmp;
}
return -IntPair.compare(ip1.getSecond(), ip2.getSecond()); //reverse
}
}
super(), when used in the constructor will call the constructor of the class which is extended. In this case, it will call the WriteableComparator constructor. You can see more details on super in the java documentation here:
Java super link
In particular, see the section titled "Subclass Constructors".
Does it call the constructor of IntPair.class?
No, It's just a argument that is passed in the super class constructor.
why is such a call necessary?
To avoid the call of no arguments constructor of the super class that is by default added by the compiler.
If there are multiple constructors in the super class then you can be specified which constructor of the super class should be called based on arguments.
Sample code: (Look at the output when KeyComparator object is created)
class WritableComparator {
public WritableComparator(){
System.out.println("default constructor is called");
}
public WritableComparator(Class<?> clazz, boolean flag) {
System.out.println("two arguemnts constructor is called");
}
}
class KeyComparator extends WritableComparator {
public KeyComparator() {
//super(); // by default added by the compiler
super(IntPair.class, true);
}
}
IntPair.class notation is used to get object describing this class. Like here:
Class<?> type = Integer.class;
This type variable is not an instance of Integer class, but instance of object describing Integer type.
Some classes requires you to pass them type of objects you want them to work with. Then, they can for example create new instances of those classes, using this type object.
more about Class class
This question already has answers here:
How can a Java class have no no-arg constructor?
(8 answers)
Closed 9 years ago.
In java tutorials,
http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor.
Can anyone provide me with an example where is this compile error possible?
class A
{
int a;
A(int a)
{
this.a=a;
}
}
class B extends A
{
B(int a)
{
this.a=a;
}
}
class C
{
public static void main(String args[])
{
B obj=new B(20);
System.out.println("a = "+obj.a);
}
}
Error:Constructor A in class A cannot be applied to given types;
{
^
required: int
found:no arguments
reason: actual and formal argument lists differ in length
class A
{
public A(int n)
{
}
}
class B extends A
{
}
Say you have a Super class
class Super {
// no constructor
// Java compiler will assign a default constructor
// Super () {}
}
and a Child class
class Child extends Super {
public Child() {
//super(); --> this statement will be inserted by default by Java compiler, even though you don't put it in your code
}
}
And If Super is like this
class Super {
Super(int a) {
// Now this is the only constructor Super class has
// Java doesn't insert a default constructor now..
}
}
Child cannot have no argument constructor, because Super doesn't have it anymore
class `Child` {
Child() {
// super();
//this will be error since there is no "no-argument" constructor in Super
}
}