I have first class for which constructor takes a parameter.
public class First {
First(Object o){
o.toString();
}
}
I have a second class which extends this first one.
public class Second extends First {
Second(Object o) {
super(o);
}
}
What I want is to keep the constructor of Second class private in order to have a possibility to instantiate the only one instance of this class (using Singleton pattern, for instance), but compiler doesn't allow me to do that.
If I can't set the constructor as private here, what can I do to allow the only one instance of the class to be created?
You can make the constructor of Second private with no problems. What you can't do is make the constructor of First private, unless you use nested classes.
As an example, this works fine:
class First {
First(Object o) {
o.toString();
}
}
class Second extends First {
private final static Second instance = new Second(new Object());
private Second(Object o) {
super(o);
}
public static Second getInstance() {
return instance;
}
}
Here it is working !!
class First {
First(Object o){
o.toString();
}
public First() {//I think you missed this
}
}
class Second extends First {
private static Second obj ;
private Second(Object o) {
super(o);
}
private Second() {
}
public static Second getInstance(){
if(obj == null){
obj = new Second(new Object());
}
return obj;
}
}
public class SingleTon {
public static void main(String[] args) {
Second sObj = Second.getInstance();
}
}
public class Second extends First{
private static final Second instance = new Second(new Object());
private Second(Object o) {
super(o);
}
public static Second instance(){
return instance;
}
}
Related
I want to do something like this:
public class Parent {
private static final Map<Class<?>, Object> map;
static {
map = new IdentityHashMap<>();
}
public Parent() {
if (map.get(getKey()) == null) {
map.put(getKey(), new Object());
}
}
private static Class<?> getKey() {
return /*something*/;
}
public static Object getValue() {
return map.get(getKey());
}
}
public class Child extends Parent {
}
Child.getValue() // returns an object
Parent.getValue() // returns other object
I tried to use MethodHandles.lookup().lookupClass() in getKey(), but it returns Parent class when calling Child.getValue() (eg:
public class Parent {
private static final Map<Class<?>, Object> map;
static {
map = new IdentityHashMap<>();
}
public Parent() {
if (map.get(getKey()) == null) {
map.put(getKey(), new Object());
}
}
private static Class<?> getKey() {
Class<?> clazz = MethodHandles.lookup().lookupClass();
System.out.println(clazz.getName());
return clazz;
}
public static Object getValue() {
return map.get(getKey());
}
}
public class Child extends Parent {
}
Child.getValue()
// console output: my.project.package.Parent
// i want: my.project.package.Child
)
How i can do this? I tried to use all cases from this: Getting the class name from a static method in Java, and in every case it prints in console parent class name.
UPD: the getValue() method should be static, i can't do anything with it.
UPD2: I know that such code is bad practice, and I know why this problem arises, but I did not write the getValue() method and it does not depend on me, and I want to find out any way to perform the task described in the question, even using reflection, the MethodHandles or something else
I got the object wolfOne of the Class Wolf, and I need to access to its variable mAlive in another Class, how may I don it?
Wolf wolfOne;
//Wolf Class
public class Wolf extends Card {
public Wolf(){
mCharacter = "Wolf";
}
public void savage(Card card) {
card.mAlive = false;
}
}
//Card Class
public class Card {
//Names
public String mCharacter;
//Status
public static boolean mAlive;
public static boolean mDefended;
public static boolean mOwled;
public static boolean mLastSavaged;
public static boolean mLastLynched;
//Constructor
public Card() {
// Do Card specific stuff.
}
}
Remove static from all of your Class variables - make them instance variables instead. Then provide typical getters/setters for each, allowing clients of the class to retrieve or mutate the value:
public class Wolf extends Card {
public Wolf(){
setMCharacter("Wolf");
}
public void savage(Card card) {
card.setMAlive(false);
}
}
public class Card {
//Names
private String mCharacter;
//Status
private boolean mAlive;
private boolean mDefended;
private static boolean mOwled;
private static boolean mLastSavaged;
private static boolean mLastLynched;
public String getMCharacter(){}
return mCharacter;
}
public void setMCharacter(String value){
this.mCharacter = value;
}
public boolean getMAlive(){
return mAlive;
}
public void setMAlive(boolean alive){
this.mAlive = alive
}
//....So on and so forth
}
static has a special meaning in Java. It doesn't mean that the variable or method is inheritable; it means that there is only one of it that belongs to the class, not the instance.
To inherit from a super class, all that is required is that it not private and the inheriting classes will get it. The following example shows this relationship.
import java.util.*;
import java.lang.*;
import java.io.*;
class A
{
public String name;
public boolean isAlive;
public A()
{
name = "A";
isAlive = true;
}
}
class B extends A
{
public B()
{
name = "B";
isAlive = false;
}
}
public class Main
{
public static void main (String[] args)
{
A a = new A();
A b1 = new B();
B b2 = new B();
b2.name = "B2";
b2.isAlive = true;
System.out.println(a.name);
System.out.println(a.isAlive);
System.out.println(b1.name);
System.out.println(b1.isAlive);
System.out.println(b2.name);
System.out.println(b2.isAlive);
}
}
And gives this output:
A
true
B
false
B2
true
This can be run here.
In the card class make the fields private not public, in oo this is called encapsulation or data hiding (look it up). Then simply add a getMAlive method that returns the mAlive value and a setMAlive method which will set it. Now in your wolf class to set mAlive you can with setMAlive(boolean). For external objects you will need to have a reference to your wolf/card and call wolfName.getMAlive()
For card...
private boolean mAlive;
public boolean getMAlive(){
return mAlive;
}
public void setMAlive(boolean value){
mAlive = value;
}
For wolf...
public void savage(){
setMAlive(false);
}
For other classes to get mAlive...
wolfName.getMAlive()
You may consider making your mAlive (and other fields in Card) protected. Protected fields can only be seen by those classes that extend them e.g. wolf. So in wolfs savage method you could do...
public void savage(){
mAlive = false;
}
But to set mAlive from other classes you would still need a setter in Card so yeah
I hope this helps :) good luck
I have generic class :
public class Test<T> {
private Test<? extends T> myInstance;
public Test<? extends T> getInstance () {
return myInstance;
}
public void setInstance (Test<? extends T> argType) {
this.myInstance = argType;
}
}
And I have two classes in my class hierarchy relations:
public abstract class Alphabet {
//code here
}
and
public class A extends Alphabet{
public A() {
super();
System.out.print("This is A call");
}
}
Finally I have a class where I want to store make generic class Test with particular type and set new Instance of Object -> A through setInstance() method:
public static void main(String[] args) {
List<Alphabet> list = new ArrayList<Alphabet>();
Test<Alphabet> tAlphabet = new Test<Alphabet>();
tAlphabet.setInstance(new A()); //Here is compilation ERROR
}
But I have got the compilation error in line tAlphabet.setInstance(new A());
What is the issue with my generic class?
Your instance is a Test object as it's currently written, and you are supplying it with an Alphabet object instead. You probably want your instance to be of type Alphabet:
public class Test<T> {
private T myInstance;
public T getInstance() {
return myInstance;
}
public void setInstance(T argType) {
myInstance = argType;
}
}
This way, your Test stores an Alphabet instead of another Test.
It seems you have made things more complicated than needed. You probably want this in your Test class instead of what you actually have:
private T myInstance;
public T getInstance () {
return myInstance;
}
public void setInstance (T argType) {
this.myInstance = argType;
}
With this arrangement you would be free to setInstance(new A()) on a Test<Alphabet> instance.
Lets assume we've got base class:
public class Base {
public Base(int i) {
/* ... */
}
/* ... */
}
We want to create singleton based on this class. The problem is that class have public constructor, so extending it will result in singleton having public constructor, too:
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
public SingletonBase(int i) { // Want to avoid this!
super(i)
}
public static void getInstance() {
return _instance;
}
/* ... */
}
Singleton, of course, cannot have public constructors, so we want to avoid this.
So, what is most elegant way/pattern to have proper Singleton with functionalities from class Base?
Edit: Modifying Base class is prohibited, since it is from an external library.
Constructors are not inherited. So just
delete this part and you'll get what you need.
public SingletonBase(int i) { // Want to avoid this!
super(i)
}
Additionally, you may want to make the Base class
abstract so that no one can instantiate it by mistake
by calling the Base constructor directly.
public abstract class Base {
public Base(int i) {
/* ... */
}
/* ... */
}
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
public static SingletonBase getInstance() {
return _instance;
}
/* ... */
}
You could make SingletonBase just a normal subclass and delegate the Singleton-part to a different class.
I don't know what your specific context is, but you would have Subclass extends Base and somewhere else you would have your SingletonContainer or something like that where you have the method public static Subclass getInstance().
That way, you would have your usual inheritance and also the Singleton effect, since the SingletonContainer would be responsible for keeping only a single instance of Subclass.
It is not because you inherit from a class that have a public constructor that you have to create the same public constructor, you can do :
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
public static void getInstance() {
return _instance;
}
/* ... */
}
Or even :
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
private SingletonBase(int i) { // Want to avoid this!
super(i)
}
public static void getInstance() {
return _instance;
}
/* ... */
}
I want to change how a method of a class executes without overriding the method, and only overriding (or ideally extending) the inner class. Assume that I cannot change the fact that I need to do this (I am modifying an existing open source code base and there would be friction to pulling out classes or whatnot).
public class A {
static class Thing {
public int value() { return 10+value2(); }
public int value2() { return 10; }
}
public String toString() {
Thing t = new Thing();
return Integer.toString(t.value());
}
}
public class B extends A {
static class Thing {
public int value2() { return 20; }
}
}
My goal is, by changing only Thing, getting B's toString() to return "30", where currently it will return "20". The ideal would be to change only the method value2 (thus leaving any other methods unchanged), but I don't know if this is possible.
Thanks
I think you need a factory method for this. Consider the following example (derived from your snippet):
static class A {
static class Thing {
public int value() {
return 10 + value2();
}
public int value2() {
return 10;
}
}
protected Thing createThing() {
return new Thing();
}
public String toString() {
return Integer.toString(createThing().value());
}
}
static class B extends A {
static class Thing extends A.Thing {
public int value2() {
return 20;
}
}
#Override
protected Thing createThing() {
return new Thing(); // creates B.Thing
}
}
public static void main(String[] args) {
System.out.println(new B());
}
Output:
30
You should be able to just extend the inner class with Thing extends A.Thing. As long as it's visible in your scope it shouldn't be a problem.
It's not possible by only changing value2. The problem is that 'new' calls aren't dispatched dynamically - the 'new' in toString will always create A::Thing. You could fix this creating a factory : something like this:
public class A {
static class Thing {
public int value() { return 10+value2(); }
public int value2() { return 10; }
}
private Thing makeThing() { return new Thing(); }
public String toString() {
Thing t = new Thing();
return Integer.toString(t.value());
}
}
public class B extends A {
static class Thing extends A.Thing {
public int value2() { return 20; }
}
private Thing makeThing() { return new Thing(); }
}