Create a final field initialized by a child class - java

I have an abstract class with subclasses that share a method that increments a value by a specific increment and is bounded by a lower limit and an upper limit. Each subclass has its own increment and its own bounds These values should all be declared final, but if I declare them final how can they be initialized by the subclasses.
Below is the only way I could think of to get it to work, but it seems rather cumbersome.
public abstract class ClassA {
protected int LOWER_LIMIT;
protected int UPPER_LIMIT;
protected int INCREMENT;
public ClassA() {
}
}
public class ClassB extends ClassA {
public ClassB() {
super();
this.LOWER_LIMIT = 0;
this.UPPER_LIMIT = 4200;
this.INCREMENT = 15;
}
}
public class ClassC extends ClassA {
public ClassC() {
super();
this.LOWER_LIMIT = 0;
this.UPPER_LIMIT = 99;
this.INCREMENT = 1;
}
}

The quite common pattern is this. You also force the subclasses to define the value.
public abstract class Base {
final protected int field1;
final protected int field2;
final protected int field3;
protected Base(int field1, int field2, int field3) {
this.field1 = field1;
this.field2 = field2;
this.field3 = field3;
}
}
public class Subclass extends Base {
public Subclass () {
super(0, 4200, 15);
}
}

Related

how to define parameterized constructor of abstract class in child class in java

how to define parameterized constructor of abstract class in child class in java
abstract class Car {
protected boolean isSedan;
protected String seats;
public Car(boolean isSedan, String seats) {
this.isSedan = isSedan;
this.seats = seats;
}
public boolean getIsSedan() {
return this.isSedan;
}
public String getSeats() {
return this.seats;
}
abstract public String getMileage();
}
public class WagonR extends Car{
protected int mileage;
protected boolean isSedan;
public WagonR(int mileage) {
super(isSedan,seats);
this.mileage=mileage;
}
}
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int carType = Integer.parseInt(bufferedReader.readLine().trim());
int carMileage = Integer.parseInt(bufferedReader.readLine().trim());
Car wagonR = new WagonR(carMileage);
wagonR.printCar("WagonR");
}
}
While passing isSedan and seats parameters in super block in WagonR constructor, getting compilation error "Cannot refer to an instance field isSedan while explicitly invoking a constructor" and "Cannot refer to an instance field seats while explicitly invoking a constructor"
Constraint is while execution only one parameter will be passed like WagonR(carMileage).
I was doing mistake by passing parameter names in super block rather than passing parameter values using which I wanted to invoke Car constructor.
//incorrect
public WagonR(int mileage) {
super(isSedan,seats);
this.mileage=mileage;
}
//correct
public WagonR(int mileage) {
super(false,"4");
this.mileage=mileage;
}
Your WagonR class shoud be like this:
public class WagonR extends Car{
protected int mileage;
protected boolean isSedan;
public WagonR(int mileage) {
super(false, "4");
this.mileage=mileage;
}
public WagonR(int mileage, boolean isSedan, String seats) {
super(isSedan, seats);
this.mileage=mileage;
}
// And don't forget override method
#Override
public String getMileage() {
}
}

OOP: inheritance with extends

Can anybody tell me why this code isn't correct?
public class Boss extends Angestellter {
Boss(String v, String n, int a) { // ERROR **
vorname = großKleinSchreibung(v);
nachname = großKleinSchreibung(n);
alter = a;
}
}
** Implicit super constructor Angestellter() is undefined. Must explicitly invoke another constructor
public class Angestellter {
protected String vorname;
protected String nachname;
public int alter;
Angestellter(String v, String n, int a) {
this.vorname = großKleinSchreibung(v);
this.nachname = großKleinSchreibung(n);
this.alter = a;
}
I dont find the error, because its exactly how its explained in the book which im using to learn oop with java.
You should call the constructor of the base class explicitly, since if you don't, the compiler adds an implicit call to the parameterless constructor of the base class, which doesn't exist in your case.
public class Boss extends Angestellter {
Boss(String v, String n, int a) {
super (v,n,a);
vorname = großKleinSchreibung(v);
nachname = großKleinSchreibung(n);
alter = a;
}
}
In simple words
You cannot override constructor of super class in JAVA
Here is your little modified code !!
public class Angestellter {
protected String vorname;
protected String nachname;
public int alter;
Angestellter(String v, String n, int a) {
this.vorname = großKleinSchreibung(v);
this.nachname = großKleinSchreibung(n);
this.alter = a;
}
...
}
public class Boss extends Angestellter {
... Other methods
}
// In main
Angestellter myObj = new Boss("asd","as",1); // It will call constructor itself ... because it is inherited !!

accessing private member of member class

I have a class A, with a private member int myMember. And a class B with a private member of the class A, called myA;
That is:
public class A{
private int myMember;
...
}
public class B{
private A myA;
}
I would like to be able to access:
B.myA.myMember;
but it seems I can't because myMember is private in A. The thing is, I need A to be defined as private for the purpose of the exercise (that also includes it can't be protected). Is there a way around this?
Thanks.
public class A {
private int myMember;
public int getMyMember() {
return myMember;
}
public void setMyMember(int myMember) {
this.myMember = myMember;
}
}
public class B{
private A myA;
public B() {
myA = new A();
myA.setMyMember(0);
int a = myA.getMyMember();
}
}
Use getters :
public class A {
private int myMember;
public getMyNumber() {
return myNumber;
}
}
public class B {
private A myA;
public A getA() {
return myA;
}
}
So now you can code :
B b = new B();
b.getA().getMyMember();
Since you've stated you can't create more public methods, aka getters, you could use reflection...
public class A{
private int myMember;
...
}
public class B{
private A myA;
private int get(){
try {
Field field = myA.getClass().getDeclaredField("myMember");
field.setAccessible(true);
return (int) field.get(myA);
catch (Exception e){
//Something went wrong, the field doesn't exist or a security exception
return null; //or return some "error number" like -10
}
}
}
If you can declare the private field as static then something like this is possible :
public class A {
private int myMember;
}
public class B {
public static void main (String[] args) {
int myMember = new A() {
public int getPrivate() {
return myMember;
}
}.getPrivate();
System.out.print("\n\t Id : " + myMember);
}
}

Is it the right way to do what Im trying? Abstract static variable?

Look on the code below. It seems to be like there is easier way to do it.
For each new Class I want to add to the system, I have to do the following in order to set the class variable(static -> maxPlayers)?
Something like Abstract static variable?
protected abstract class Class{
protected abstract int getMaxPlayers();
public class Soldier extends Class{
public static final int maxPlayers = 4;
#Override
protected int getMaxPlayers() {
return Soldier.maxPlayers;
}
}
public class Demoman extends Class{
public static final int maxPlayers = 2;
#Override
protected int getMaxPlayers() {
return Demoman.maxPlayers;
}
}
public class Scout extends Class{
public static final int maxPlayers = 4;
#Override
protected int getMaxPlayers() {
return Scout.maxPlayers;
}
}
public class Medic extends Class{
public static final int maxPlayers = 2;
#Override
protected int getMaxPlayers() {
return Medic.maxPlayers;
}
}
}
its just like i have to repeat this template:
public static final int maxPlayers = 2;
#Override
protected int getMaxPlayers() {
return Medic.maxPlayers;
}
And i think it is not correct to do so.
First of all, you shouldn't name your class Class (not even for examples). Choose a better name.
Secondly, it seems like an enum is what you really need here:
public enum Army {
SOLDIER(4),
DEMOMAN(2),
SCOUT(4),
MEDIC(2);
private final int maxPlayers;
private Army(int maxPlayers) {
this.maxPlayers = maxPlayers;
}
public int getMaxPlayers() {
return maxPlayers;
}
}
No, you can't have an static variable in a base class that has a different value for each subclass (as far as I can tell, this is what you'd ideally want to do).
The way you did it is one option, another is using a non-static variable, as below.
And your variable should preferably have less scope than your getter function.
class Class
{
private final int maxPlayers;
Class(int max)
{
maxPlayers = max;
}
public int getMaxPlayers()
{
return maxPlayers;
}
}
class Soldier extends Class
{
Soldier()
{
super(4);
}
}
To increase readability and modifiability, you may want to consider replacing 4 here with an enum or similar.
Another way:
abstract class Class
{
public static int MAX_PLAYERS_SOLDIER = 4,
MAX_PLAYERS_DEMOMAN = 2,
...;
protected abstract int getMaxPlayers();
}
class Soldier extends Class
{
#Override
protected int getMaxPlayers()
{
return MAX_PLAYERS_SOLDIER;
}
}

Accessing an Object from other Methods

How do I access an object, that was instantiated in the constructor, in another method? (e.g. object b below) What is the best way to instantiate this object so that all of my class methods have access to the same object?
public class ClassA{
private final int size;
public ClassA(int N){
size = N;
ClassB b = new ClassB(size);
}
public void doSomething(){
b.doSomething();
}
}
You just need to assign it to a field:
public class ClassA{
private final int size;
private final ClassB b;
public ClassA(int N){
size = N;
b = new ClassB(size);
}
public void doSomething(){
b.doSomething();
}
}
Define ClassB b as instance variable.
public class ClassA{
private final int size;
ClassB b;
public ClassA(int N){
size = N;
b = new ClassB(size);
}
public void doSomething(){
b.doSomething();
}
}
Declare it as a field just as you have done with size:
public class ClassA{
private final int size;
private final ClassB b;
public ClassA(int N){
size = N;
b = new ClassB(size);
}
public void doSomething(){
b.doSomething();
}
}
you can simply create a property/field of type B
public class ClassA{
private final int size;
private B bInstance;
public ClassA(int N){
size = N;
bInstance = new ClassB(size);
}
public void doSomething(){
b.doSomething();
}
}

Categories

Resources