I am a noob and I need some help.
So I have this abstract class with a private variable. I also have a method named getThing() to return that.
I have a class that extends that abstract class, and it too has a private variable and a method that overrides the original to get the value from the abstract class.
Well the only way to be able to access both values is by creating a second method in the subclass called getSuperThing, and using the super in that. Well I was just wondering out of curiosity if there was some easier way to do that and be able to access the abstract classes method by doing something like objectNae.super.getThing().
Thanks ;)
The variable is private and so can only be referenced by the containing (abstract) class. As you have stated, from a subclass, you can invoke the superclass method (rather than the overridden one).
If you want to make the variable accessible from the subclass directly (without requiring the accessor method), make it protected instead. Here is the documentation on Controlling Access to Members of a Class.
If I understand your question correctly, then you just shouldn't override the abstract class' method in the concrete subclass. No need to, unless you need the subclass to return a different value than that returned by the abstract class (and that would suggest poor design).
Rather, the abstract class' method will be accessible as a method of the subclass.
So, if you have:
public abstract class AbstractClass {
private int value = 3;
public int getValue() {
return value;
}
}
public class ConcreteClass extends AbstractClass {
}
then you should be able to do:
new ConcreteClass().getValue()
I don't think you have other ways than calling super.getThing() in the subclass's getThing() or getSuperThing() method. Abstract class must be subclassed before being used.
Related
While reviewing the java code, I have seen that the constructor of an abstract class is made protected.
public abstract class A {
protected A() {
}
}
What
Abstract means to me is that you can't create the instance of this
class and use this class after extending
.
And protected constructor also ensures that.
What is the point of doing two things, one making constructor protected and second making the class abstract for solving the same purpose.
Making the constructor protected doesn't prevent other classes from the same package or other classes that extend this class from instantiating the class using this constructor. Therefore the abstract keyword is required to prevent instantiating.
You can declare the constructor of an abstract class as public, but you still won't be able to instantiate this class, so it's pointless. On the other hand, a private constructor will not be usable by sub-classes of your abstract class (only be other constructors of the abstract class itself). Hence, any constructor of the abstract class that should be available to all sub-classes of the abstract class should be protected.
Of course, in your particular example there's no need to declare the constructor at all, since it has an empty body and there are no other constructors. This means the compiler will generate a parameter-less constructor with an empty body anyway.
It's true that reducing the visibility of the constructor in an abstract class (from public to protected) changes nothing regarding the inability of code to directly instantiate the abstract class.
However, that is not the point. One makes the constructor protected just to control scopes, in the same way one makes member properties private.
Here's a modified version of the same class showing that the point is not to prevent instantiation:
public abstract class A {
protected A() {
this(0);
}
private A(int a) {
// not accessible to anyone but members of A
// the point is not to prevent instantiation, but to restrict access
}
}
If making the constructor protected were meant to prevent instantiation, then one could argue that instantiation would be possible within the abstract class itself or its subclasses.
I have a class that offers a collection of static utility-type methods.
On the one hand, I don't want the class to be able to be instantiated. On the other hand, I don't want to send the signal that the class should be inherited from (not that I think that it's likely).
Should this class be abstract or not?
make the class final and make the default constructor private and do not provide any public constructors. that way no one can subclass it or create an instance of it.
Don't declare it abstract; declare a private constructor, so no one, not even a subclass, can instantiate an instance of your utility class.
You can declare your class final, although if all constructors are private, then no one will be able to subclass it anyway.
To borrow the idea from Pshemo's comment in another answer, throw a RuntimeException in the constructor to prevent reflection's setAccessible method in AccessibleObject from allowing instantiation:
public class MyUtility
{
private MyUtility()
{
throw new RuntimeException("Instantiation of MyUtility is not allowed!");
}
public static void utilityMethod()
{
// Your utility method here.
}
}
Although a top-level class can't be declared static, you can make the class non-instantiable (and practically 'static') to other classes by declaring the default constructor private, which forbids instantiation because no constructor is visible.
Another version of #mre's answer
enum MyClass{
;//this semicolon indicates that this enum will have no instances
//now you can put your methods
public static void myMethod(){
//...
}
}
Enum by default is final and its constructor is private. Also you cant create its instance with reflection because it checks in Constructor#newInstance if you are trying to instantiate Enum object.
What is contained in a class has no bearing on whether it should be abstract. The key take away: an abstract class must have another class extending it (a 'concrete' class); only that concrete class can be instantiated.
To prevent it from being extended, use final.
To prevent it from being instantiated, make the constructor private.
Observe that in Java these are discrete concepts.
No, it is a utility class.
It should be final with a private default constuctor, to avoid instantiation.
If you have checkstyle enabled you would get a warning if you dont do it.
Seriously, you don't have to do anything. Nothing bad will happen, nobody is going to instantiate/subclass your class.
In addition to all the other calls to give the class a private constructor, you should also make it final so that it is clear nothing can subclass it.
public final class Utils
{
// prevent accidental construction.
private Utils()
{
}
public static void foo()
{
//util code here
}
}
I have an abstract class A
I have about 10 classes that extend A
Class A has one or two static methods and it makes sense that these are static, because they belong to the 10 classes, NOT instances of them. One static method e.g. is called getAllFromX, which gets all all instances of the class from X, whatever that may be, it may be a server, well it actually is, but it doesn't matter. So you see it makes sense these methods are static and are not bound to an instance.
At the same time class A has a NON-static abstract method, each subclass overrides this method (just returns a string). I cannot make it static because static methods cannot be overridden (...).
To summarize: abstract class A has a static method and a abstract non-static method, that is overriden by the subclasses. I cannot make the second method static because it must be overriden. On the otherhand I could make the first method non-static, but it would be very ugly and bad programming style, so I'll leave it that way.
The catch? The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Is the "easiest" way to use reflection to get this done? I mean...really?
Like e.g., I get the class the static method is in:
Class<?> cl=new Object(){}.getClass().getEnclosingClass(); (a hack I found here, thank god...)
I then use getConstructor to construct an object of this subclass.
And then I use this object to call the non-static method.
Really?? Can it not be done easier? I mean that is if I want to design my program conceptually correct...
Coming from C# I don't like that (and the type erasure thing). It is just ugly. Doable but ugly. And a big stumbling block, at least for beginners. EDIT: after reading it again, I'd add: /rant end. Sorry, but I actually care.
I think what you in fact need is the following:
public class A {
public static Set<A> getAllFromX() {
...
}
}
public class B extends A {
public static Set<B> getAllFromX() {
...
}
}
public class C extends A {
public static Set<C> getAllFromX() {
...
}
}
(Just as the valueOf() and values() methods in enums, which is redefined in every Enum subclass, because static methods can't be inherited)
In this case, each class has its own static method doing whatever it wants. But your question doesn't make much sense because it says:
The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Indeed, the static method is not inherited by the subclass. Static methods are never inherited. If you define a static method foo() in A, and call
B.foo();
the compiler doesn't refuse to compile it, but it translates it to
A.foo();
So, there's no way to do in foo() something that depends on the class on which foo() is called, since it's always A.
You can always use reflection to invoke a method using class name e.g.
Object objectX = ClassX.class.newInstance();
//get your method passing argument types as second param
Method method = ClassX.class.getDeclaredMethod("methodX", null);
//invoke your method passing arguments as second param
method.invoke(objectX, null);
Since you mentioned your static method doesn't use any instance but you are using reflection to get the instance hence I am really not sure, how does it fit in your requirement though.
I think making it as an implemented method (non-static) in your abstract class is a better choice. That way you implement it once but its available in in all your 10 extending classes.
I think your problem is one of larger design. A different object should be responsible for retrieving instances of A or its subclasses. As you can see, relying on a static method to be replaced by subclasses does not work well. Without knowing more about the problem domain, it's hard to give a good answer, but I would consider something similar to the Abstract Factory pattern.
Broadly speaking: Define an abstract class, AFactory, with a method Collection getInstances(). Extend AFactory for each of the concrete subclasses of A you need to return and implement that logic in the overridden getInstances() method as appropriate. You may also provide a static method on the abstract AFactory, getFactory(Class), to get the appropriate factory subtype at runtime.
I'm kinda unsure about the following question:
If Launchable is a Java interface, what objects can be passed into the following method? What methods could be invoked on item inside this method?
public void prepareForLaunch (Launchable item) {
// some code
}
My current answer is:
From the above information, the only objects that can be passed into the method are objects that where instantiated as subclass types of the interface Launchable.(?) The methods that could be invoked on item inside the method would have to be public methods or protected methods within the same package. These methods would also have to be to be intended for a subclass of Launchable object since it is only in abstract and actual(concrete) classes where a method body’s definition can exist.
I was wondering if someone here can check my answer and add any suggestions. Thanks!
You can only pass in instances of classes that implement Launchable (either directly, or by inheritance from a superclass). You can also pass in null.
Inside of the method, you can call all the methods defined in Launchable (and in Object).
These methods would be defined in the Launchable interface, but implemented in the actual class (a fact that is guaranteed by the Java type system, which won't let you have classes with incomplete interface implementations, those would need to be declared abstract and cannot be instantiated).
If you need to call any other methods you need to know that the object in question also implements some other interface (or is of a given class), and do a typecast to that first.
Since you stated that Launchable is an interface, an instance of any class that implements Launchable could be passed to prepareForLaunch. Any class implementing Launchable would have to implement the methods defined in the interface and thus any method of Launchablecould be invoked to objects given to prepareForLaunch.
You are right about the first part. About the methods you can invoke: If you are not using casting then you can only invoke public\protected within the same package of Launchable. If you will use casting you can extend the range of the methods you can invoke to the methods in the casted-to class.
Consider this code:
public interface Launchable
{
public void aMethod();
}
public class SomeClass implements Launchable
{
public void aMethod()
{
}
public void bMethod(){}
}
Without casting youll be able to call
item.aMethod();
With Casting youll be able to call:
((SomeClass)item).bMethod();
you should use implements statement ,
public void prepareForLaunch() implements Launchbla {
}
It is not possible to create an object by directly calling the constructor of an abstract class. The constructor of an abstract class can be called only from a derived class. It therefore seems to me that constructors of an abstract class must be either protected or package-private (the latter for the unusual cases of restricting use of a constructor to derived classes within the package). Yet Java allows the constructor of an abstract class to be public.
Are there any circumstances in which it is useful to declare the constructor of an abstract class to be public, rather than protected or package-private?
This is not quite a duplicate of the question "Abstract class constructor access modifier": clearly you can declare a constructor to be public; I want to know whether there is ever any good reason to do so. It seems to me that there is not. I see that C# has a similar peculiarity.
The answer is the same for java:
THere's no reason for a public constructor for an abstract class. I'd assume that the reason that the compiler doesn't complain is as simple that they just didn't spend time covering that since it really doesn't matter if it's public or protected. (source)
You can't call a constructor of an abstract class from anything other than a direct subclass.
So adding a special rule for access modifiers of constructors of abstract classes wouldn't add something useful to the language.
One thing that looks like an exception from this rule - if the abstract class only defines a default constructor, then the subclass does not have to implement a constructor: this is legal:
public abstract class A {
public A() {}
}
public class B extends A {}
So we can create a B by calling new B() - but note, that we still create a B and not an A. And, again, it doesn't matter if the constructor in A is public or protected. It just shouldn't be private, but the compiler will notice and complain...
Actually we invoke an "invisible" public default constructor on B which does a simple super() call...
The visibility also infuences what is shown in the javadoc (if it's selected to exclude certain visibility levels). As it doesn't matter otherwise, that could be a usage for a public constructor of an abstract class.
If you provide no constructor, then the default constructor is public if the class is public. Easiest option would be to allow that, rather than forcing protected constructors.
In that sense the reverse question may make it clear: why didn't they force protected constructors in abstract classes? Because public constructors won't change anything, so it would just take time and add complexity.
Call me a heretic, but ... I see at least one use for a constructor in an abstract class.
That is: to specify what the constructor parameters look like.
Specify an abstract constructor (thus making the class abstract). Derived classes have to implement this constructor with its specific signature to lose abstract status.
I see no other way to specify mandatory constructor signatures (help me out if you do).
You can have a public constructor if you do not define in a constructor in the sub-class.
example
abstract class Animal {
String name;
public void Animal(String name) {
this.name = name;
}
}
class Cat extends Animal{
public String sayMayName() {
return this.name;
}
}
myCat = new Cat("tester");
name = myCat.sayMyName();
if no constructor is defined the parent class constructor will be called, if it is not public it will not work. This I think is more elegantly done with a factory pattern, but I used it in practice in PHP and it works fine.