I want to create a solution for the following problem without much redundancy:
I have an abstract class Unit, subclasses SubUnit1 and SubUnit2. All Units have a maxValue, which differs from SubUnit1 to SubUnit2, but should be the same for all instances of the same sub unit at any time.
I don't want to copy all the setters, getters or some kind of method around these values, because they are identical for all subclasses. I also don't want to use normal paramters and hand down the methods to subclasses and update every single instance of these subclasses if necessary. And somehow get the current value when I create a new instance.
Is there a way to declare some sort of static parameter and methods in the parent class Unit, that differ in the different subclasses?
You could define a protected constructor in the parent class that accepts the value of the MAXVALUE
public abstract class Unit {
private final int maximum;
protected Unit(int maximum) {
this.maximum = maximum;
}
public int getMaximum() {
return maximum;
}
}
Then in your derived classes you expose constructors that call the parent's constructor with a fixed value, unique per subclass.
public class SubUnit1 {
private static final int SUBUNIT1_MAX = 10;
public SubUnit1() {
super(SUBUNIT1_MAX);
}
}
No, but using an interface you may express that a UNIT should have a MAXVALUE.
public interface IUnit
{
public int getMaxValue();
}
public class SubUnit implements IUnit
{
private static final int MAX_VALUE = 48;
#Override
public int getMaxValue() {
return MAX_VALUE;
}
}
Related
Given the question - "All game objects provide the ability for external code to obtain their size. However, they do not provide the ability to have their size changed once it is created."
If I have a parent class with private fields such as this GameObject class:
public abstract class GameObject {
private int size;
public void setSize(int size) {
this.size = size;
}
}
and a children classes such as
public class Dinosaur extends GameObject {
public Dinosaur() {
this.setSize(100);
}
}
public class Jeep extends GameObject {
public Jeep() {
this.setSize(10);
}
}
How do I ensure that the size is not changed after the object is created?
I am confused because if I make the setter method for size private then I cannot set the size for each GameObject individually upon creation.
EDIT: Added second child class for clarity.
If you need to make the size variable unchangeable then you should use final modifier.
There are 2 ways to set the value for this kind of variables: 1) constructor 2) inline. As long as you would like to have an option to set your custom value in the client code for each object, you should use constructor:
public abstract class GameObject {
private final int size;
public GameObject(int size) {
this.size = size;
}
}
public Dinosaur extends GameObject {
pubilc Dinosaur(int size){
super(size);
}
}
There is no need in setter method in that case.
size can be final and size value passed in the constructor. Also you do not need a setter. You can make only the necessary getter.
public abstract class GameObject {
private final int size;
public GameObject(int size) {
this.size = size;
}
public int getSize() {
return this.size;
}
}
They're a few things wrong with your code.
First if the class shouldn't have the ability to set the size after creation, why provide a setter in the first place?
Second, a subclass could override your setSize method in the abstract class and do whatever it wanted. If you want inheritance do this:
public abstract class GameObject {
private final size;
public GameObject(int size){
this.size = size;
}
}
public class Dinosaur extends GameObject {
public Dinosaur(int size){
super(size)
}
}
No setter is provided and the size must be made available at construction time. If you want a method to do it, make the method final. Like this:
public final setSize(int size){
this.size = size;
}
By making it final the subclasses have to except the method as it is, no overriding.
Another approach is, make this class immutable. You don't use setters, but you can have getters, and the class would be made final, so no subclassing.
public final Dinosaur {
private final int size;
pubilc Dinosaur(int size){
this.size = size;
}
public int getSize(){
return this.size;
}
}
(Note: I'm assuming you meant to have Dinosaur extend GameObject.)
You could override the setSize() method and throw an exception:
public class Dinosaur extends GameObject {
...
#Override
public void setSize(int size) {
throw new UnsupportedOperationException("can't change dinosaur size");
}
}
Given the question - "All game objects provide the ability for
external code to obtain their size. However, they do not provide the
ability to have their size changed once it is created."
The usual way that this is done is by having the constructor of the parent class accept a size argument. This argument sets the value of an immutable size field. Subclasses may easily access this value, but they are unable to change it once it has been set. This is the most object-oriented way in which to meet the listed requirements.
For example:
public abstract class GameObject {
private final int size;
public GameObject(int size) {
this.size = size;
}
public int size() { return this.size; }
:
:
}
and a child class:
public class Dinosaur extends GameObject {
public Dinosaur() {
super(100);
}
:
:
}
Although there is some discussion in this thread about how subclasses may dynamically change the size field, a better design would be to use an immutable design like the one presented here and have client code request a new object with a different size if needed (say, with a copyOf() method). Immutable designs have several advantages over mutable ones and are usually the way to go when planning value classes.
I have one class (class util) for generating password(it has only one public static method ). Here two ways are : To make it abstract so no one can create its instance
public abstract class PasswordGenerator {
public static String randomstring(int lo, int hi) {
// Some logic , doesn't matter
return "";
}
}
or to make its constructor private. So What's the best approach to do that ?
public class PasswordGenerator {
private PasswordGenerator() {
}
public static String randomstring(int lo, int hi) {
// Some logic , doesn't matter
return "";
}
}
So What's the best approach to do that ?
You should definitely not make the class abstract, as this might indicate to other developers, that it is intended to be extended (and therefor instantiated).
Having a class technically being able to be instantiated is a minor problem.
But in this SO thread you can see a workaround, that uses a private constructor in combination with making the class final.
Make both the class final and the constructor private.
With the final keyword you clearly express the intent that the class is not made to be inherited.
With the private constructor you clearly express the intent that the class is not made to be instanciated.
public final class PasswordGenerator {
private PasswordGenerator() {}
public static String randomstring(int lo, int hi) {
// Some logic , doesn't matter
return "";
}
}
I have a base class
public class base
{
//some stuff
}
and several subclasses
public class sub1 extends base
{
static int variable;
}
public class sub2 extends base
{
static int variable;
}
etc
The static int variable exists in every subclass because I store in it information that is characteristic for every subclass. But it would be better if there was a way to move static int variable to base class in the way that it still will be different for every subclass.
In the way that it is now I am repeating myself, when adding some another subclass, it's a bad practice.
So anyone has some idea how to acomplish this? Maybe there's a design pattern that fits to this situation?
You cannot move all the different static variables from derived classes into the base class, because static variables are one-per-class; you want your variables to be one-per-subclass, which is not allowed.
You could work around this issue by defining a registry of subclasses in your base class, and store the int for each subclass there. However, this would add a lot more complexity, and it is not clear how you would differentiate between subclasses in the superclass.
Your current solution appears optimal.
Don't use a static field for this - that's not the way to go, because static fields of a subclass do not "override" those of a super class.
Instead, because the values are constant for a given class, use a final instance field:
public class Base {
protected final int variable;
public Base() {
this(5);
}
protected Base(int v) {
variable = v;
}
}
public class Sub1 extends Base {
private static int v = 7;
public Sub1() {
super(v);
}
}
Now the variable is fixed and accessible to all instances.
You can certainly move variable into the base class, but it cannot be static. Alternatively, you can make static getters which you override in each subclass. Here is an example of both:
public class base {
protected int variable;
protected static int getVariable() {
return -1;
}
}
public class Sub1 extends base {
public Base() {
variable = 0;
}
protected static int getVariable() {
return 0;
}
}
public class Sub2 extends base {
public Sub2() {
variable = 1;
}
protected static int getVariable() {
return 1;
}
}
As a design principle, it is somewhat rare (in my opinion) that you genuinely want static methods. Usually you will have some instance of the class around that you are working with. If you want a whole bunch of objects to share some common behavior which you configure at runtime, you might want to check out the flyweight pattern.
I have a super class 'BuildingMaterial' and loads of subclasses, i.e. Stone, Wood, Clay, etc.
All subclasses behave similarly: 1 int field that stores the amount of a building material in units. They can be constructed parameterless or with an int. I already know that ALL subclasses of BuildingMaterial will have these two constructors, how do I avoid coding them into every single class?
Here's an example of what I don't want to do in every class:
public final class Stone extends BuildingMaterial {
private int amount;
//constructors
public Stone() {
amount = 0;
}
public Stone(int i) {
amount = i;
}
//methods
public int getAmount() {
return amount;
}
}
Sadly, the answer is you can't. This is a limitation of the Java language. Each class needs its own constructors—you can't simply inherit them from a parent class. The only constructor the Java compiler will generate for you is the default constructor (no arguments), and it only generates that if you don't specify any constructors at all.
The best you can do here is to refactor your code so amount is in the superclass:
public abstract class BuildingMaterial {
private int amount;
//constructors
public BuildingMaterial() {
this(0);
}
public BuildingMaterial(int i) {
amount = i;
}
//methods
public int getAmount() {
return amount;
}
}
And then make use of super calls to delegate the superclass's constructor in your subclasses:
public final class Stone extends BuildingMaterial {
//constructors
public Stone() {
super();
}
public Stone(int i) {
super(i);
}
}
Note that I changed the body of your no-argument constructor from amount=0; to this(0);. I personally think this is better style because, if you decide to add other initialization code to your constructor body, you only have to add it to the 1-argument constructor, and the zero-argument constructor will just delegate all the work to it.
You have to use inheritance
public abstract class BuildingMaterial {
private int amount;
//constructors
public BuildingMaterial() {
amount = 0;
}
public BuildingMaterial(int i) {
amount = i;
}
//methods
public int getAmount() {
return amount;
}
}
public class Stone extends BuildingMaterial {
public Stone() {
super();
}
public Stone(int i) {
super(i);
}
}
This way all subclasses of BuildingMaterial can give access to amount through getters and setters.
You may have amount declared as protected so you wont need getters or setters to access that field inside subclasses.
use super keyword to reduce your code but the super is to be the first line inside the constructor
public class Stone extends BuildingMaterial {
public Stone() {
super();
}
public Stone(int i) {
super(i);
}
}
If all classes has the attribute amount, then that attribute can be inherited from parent. Define amount in your parent class BuildingMaterial and then call the parent constructor from your child classes constructors using super to set the amount value.
Its unclear what you want to avoid in your question... assuming you are talking about avoiding writing multiple constructors in all the subclass. I believe its not possible to do so. below post of defining BuildingMeterial constructor and calling the super() from baseClass will be the best solution to use.
A friend of mine was asked that question in his on-phone job interview a couple of days a go.
I don't have a clue. can anyone suggest a solution?
(His job interview is over. just out of curiosity now )
10x.
Mark constructor as private
Provide a static method on the class to create instance of a class. This will allow you to instantiate objects of that class
I don't know what they mean exactly mean by a final class. If they mean a class that cannot be extended by inheritence, than clearly this cannot be done, except by marking that class with final (or sealed, or whatever the language keyword is).
But if the mean final as in immutable, such that a derived class can't modify the value of the fields in the class,than the base class should have all of the fileds and accessor methods private.
Create a private constructor without parameters?
public class Base
{
private Base()
{
}
}
public class Derived : Base
{
//Cannot access private constructor here error
}
Make all the constructors of that class as private to stop inheriting, Though not recommended.
public class Immutable {
private int val;
public Immutable(int v)
{
this.val = v;
}
public int getVal() { return this.val; }
}
You can make your class immutable without using final keyword as:
Make instance variable as private.
Make constructor private.
Create a factory method which will return the instance of this class.
I am providing immutable class here in Java.
class Immutable {
private int i;
private Immutable(int i){
this.i = i;
}
public static Immutable createInstance(int i){
return new Immutable(i);
}
public int getI(){return i;}
}
class Main {
public static void main(string args[]){
Immutable obj = Immutable.createInstance(5);
}
}
Static classes can't be inherited from