Call Super-Constructor multiple times - java

In my current programming project I have some basic classes, like Numbers or ImageSets. In other classes I use these to display Information. I thought the easiest way (not so much coding) is to let the Display-Classes extend the base-Classes.
But at one Class (TwoDigits) I need two instances of the superclass (ImageSet). Is this possible? Normally you would call super(), but a second super() call is not allowed...
Here is some code of the Number-Class: (Element is another abstract selfmade class)
public class ImageSet extends Element{
private int x;
private int y;
private int imageIndex;
private int imagesCount;
public ImageSet(int x,int y,int imageIndex,int imagesCount, boolean ignoreDimension) throws IOException, UnequalDimensionsException {
if(!ignoreDimension) {
[...]//Check for equal Dimensions, otherwise throw UnequalDimensionsException
}
this.x=x;
this.y=y;
this.imageIndex=imageIndex;
this.imagesCount=imagesCount;
}
[...]
}
Here is some code from the Base-Class (TwoDigits):
public class TwoDigits extends Element{
ImageSet tens;
ImageSet ones;
Dimension d = null;
public TwoDigits(int x, int y, int imageIndex, int imageCount, boolean ignoreDimension) throws UnequalDimensionsException, IOException{
tens = new ImageSet(x,y,imageIndex,imageCount,ignoreDimension);
String imageIndexFormatted = String.format("%04d", imageIndex);
d = StaticHelpers.getImageDimension(new File("data/"+imageIndexFormatted+".png"));
ones = new ImageSet(x+d.width,y,imageIndex,imageCount,ignoreDimension);
}
[...]
}
I would like to change the SuperClass of TwoDigits to ImageSet to save some code in other classes.
Thanks for any help.

Related

How to call the variables (length,breadth,height) from another class constructor

How to call the variables (length,breadth,height) from another class constructor
trying to call the variables length,breadth,height from class A
unable to do so
class A {
int length;
int breadth;
int height;
A(int length,int height,int breadth)
{
this.length=length;
this.height=height;
this.breadth=breadth;
}
}
class B extends A
{
public void display()
{
System.out.println("Length of the rect is "+length);
System.out.println("Height of the rect is "+height);
System.out.println("Breadth of the rect is "+breadth);
}
}
class Inheritence
{
public static void main(String [] args)
{
new A(5,6,7);
new B().display();
}
}
I trying to call the variables length,breadth,height from class A
No you probably want to use variables from an A instance.
I think that what you need is a copy constructor defined in B that takes as parameter a A.
So define it in B such as
public B(A a){
super(a.length, a.breadth, a.height);
}
And now you can do :
A a = new A(5,6,7);
new B(a).display();
A objA = new A(5,6,7) - makes an object called objA and sets properties length, breadth and height to 5,6,7 respectively.
B objB = new B() - makes an object called objB with new properties length, breadth and height and doesn't set them at all, so there is nothing to display.
If you want to set the values to properties of class B, make the constructor in class B and assign the values to fields length, breadth and height which are inherited from A.
There are 2 things you need to do:
Change the access modifier to protected (read about it here)
Create a constructor in B that sets the values for these parameters, e.g.
public B(int length, int breadth, int height) {
super(length, breadth, height);
}
Once done, B will have access to these members and you will be able to print the values.

Inherit subclass variable by super in Java

This title does not express what I mean quite well, I apologize, but it is difficult for me to express it better, because I don't quite understand what's going on due to lack of OOP knowledge and experience.
I am building a basic game, which is going to have the player run around a board with a 'hero' sprite, being chased by a 'badGuy' sprite. Because the two sprites share 5-6 methods, I decided to make a super class 'Sprite' and two classes 'Hero extends Sprite' and 'BadGuy extends Sprite'. Now for all those super methods, including stuff like:
getX(); getY(); getBounds(); render();
to work I need the super class to track the location of 'Hero' and 'badGuy'. So I implemented 'Sprite' like this:
package game.sprites;
import javafx.scene.shape.Rectangle;
import javax.swing.*;
import java.awt.*;
public class Sprite {
public static int x;
public static int y;
private int imageWidth;
private int imageHeight;
public Image image;
public Sprite(int x, int y) {
Sprite.x = x;
Sprite.y = y;
}
public static void render(Graphics g, Image image) {
g.drawImage(image, x, y, null);
}
public Image loadImage(String filePath) {...}
public void getImageDimensions() {...}
public Rectangle getBounds() {
return new Rectangle(x, y, imageWidth, imageHeight);
}
public Image getImage() {
return image;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
The problem kicks in when I want to give different starting coordinates to 'Hero' and 'BadGuy' objects. Currently if I set them different, the second call of 'Sprite' overrides the first and both start at the same spot (which would be very frustrating if your goal is to run from 'badGuy').
'Hero' and 'BadGuy' are currently initialized this way:
public class BadGuy extends Sprite {
public BadGuy() {
super(x, y);
initBadGuy();
}
public void initBadGuy() {
loadImage("resources/craft.gif");
getImageDimensions();
x = 860; // Hero x = 20;
y = 560; // Hero y = 20;
}
So what I tried to do is make the subclasses override Sprite's x and y. But I googled it and I understand that this is very bad idea and thus it is not possible. So my question is something like: How can I make 'Sprite' inherit subclass 'x' and 'y' variables and perform the necessary methods when the certain subclass is called.
Now that I look at it - both the constructor and init<>() are identical for the subclasses, so maybe they can be implemented in 'Sprite' instead? Just a thought, but I'm getting quite confused already, so no idea.
Thanks.
You are getting this problem because x and y are declared as static fields in your Sprite class.
From JLS 8.3.1.1. static Fields
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (ยง12.4).
Use following code:
Change your Sprite Class like below:
public class Sprite {
public int x;
public int y;
....
}
BadGuy class:
public class BadGuy extends Sprite {
public BadGuy(int x, int y) {
super(x, y);
...
}
....
}
Hero class:
public class Hero extends Sprite {
public Hero(int x, int y) {
super(x, y);
...
}
....
}
From Main class do following: //From where you want to create Object of both classes
public static void main(String[] args){
Hero hero = new Hero(20,20);
BadGuy badGuy= new BadGuy(860,560);
}

can you make a public member of the superclass a protected member in a subclass?

Like what the title says, Can you make a public member of the superclass a protected member in a subclass? I had this question in my exam today, and I'm fairly new to programming. Can you explain how?
public class Animal {
int lifeExpectancy;
private int weight;
protected gender;
String name;
public String type;
String genders;
public Animal(int le, int w, char g, String n){
lifeExpectancy = le;
gender = g;
weight = w;
name = n;
}
this is the subclass
public class Pet extends Animal{
private String home;
private Boolean biten;
String message;
public Pet(int le, int w, char g, String n, String h, Boolean b) {
super(le, w, g, n);
lifeExpectancy = le;
gender = g;
weight = w;
name = n;
home = h;
biten = b;
}
No. Lets say you have A extends B, remember that this means you can always use an A as a B.
B b = new A();
So it can't be allowed for A to remove or restrict anything that B does, it can only extend it.
Overriden method:
must not have a more restrictive access modifier
may have a less restrictive access modifier.
level of restriction (from the most restrictive):
private
defualt
protected
public
Declaring member variable (tutorial):
you will shadow variable
In Java Member is Constructor, Field or Method.
class X1 {
public int x;
public X1() {
}
public void x () {
}
}
public class X extends X1 {
protected int x;
protected X() {
}
protected void x () {
}
}
compiler finds only one error in above
- Cannot reduce the visibility of the inherited method from X1
and there is no way it might allow it. As for constructor and field we do not change visibility of super class members we are just declaring the new ones
You can just inherit the properties. That's it.
Consider a case that If you use a subclass in place of superclass and you modified the accessor of that subclass, that breaks OOP rules.
You can not reduce the accessibility of an inherited item. And only instance methods are inherited. So you can re-define an instance or static property (not a method) in a child class with lower accessibility.
For static methods you still can not drop the accesibility though they are not inherited.

Java extends strange output

I have written a small program in Java, a there is something I just do not understand.
Program that I have wrote has 3 classes kingClass, masterClass, and workClass. workClass extends masterClass.
Program: in the main class (kingClass) I have declared masterClass and workClass, and with the masterClass I have given values to variables x, and y. In the end of kingClass I have called a addNum function that sum two numbers from the masterClass.
Now the problem: I expected when I run the program that it will give me a sum of two numbers I have given with input, not the sum of number that I have given value in constructor.
How can write this program so that addNum returns the value of the sum of number I have enterd.
Sorry for bad english, Thank you..
kingClass
public class kingClass
{
public static void main(String[] args)
{
masterClass mClass=new masterClass();
mClass.setX(10);
System.out.println(mClass.getX());
mClass.setY(5);
System.out.println(mClass.getY());
workClass wClass = new workClass();
System.out.println(wClass.addNum());
}
}
masterClass
public class masterClass
{
private int x;
private int y;
masterClass()
{
x=0;
y=0;
}
public void setX(int a) {x=a;}
public void setY(int a) {y=a;}
public int getX() {return x;}
public int getY() {return y;}
}
workClass
public class workClass extends masterClass
{
int num=getX()+getY();
public int addNum() {return num;}
}
The following two statements:
masterClass mClass=new masterClass();
workClass wClass = new workClass();
create two objects that are completely independent from one another. When you modify one, this has no effect on the other.
Did you mean:
public static void main(String[] args)
{
workClass wClass = new workClass();
wClass.setX(10);
System.out.println(wClass.getX());
wClass.setY(5);
System.out.println(wClass.getY());
System.out.println(wClass.addNum());
}
?
The fact that workClass extends masterClass enables you to use masterClass's public methods on an instance of workClass.
There is also a bug in your addNum() method:
public class workClass extends masterClass
{
public int addNum() {return getX() + getY();}
}
Your current implementation adds the numbers together at construction time, disregarding any changes made to x and y post-construction.
You don't assign the value to x and y when you create the object of WorkClass. Extending a class just means that the data members are inherited. It doesn't mean that all the objects that you create of the base class will automatically be copied to the derived class when you create a new object of derived class.
You've assign values to x and y on the mClass instance, not on wClass, so num will always be zero.
You have two errors there:
First, you are setting the values on one object (first masterClass instance), and adding values from another one (the workClass, which is a different object instance).
Second: Your num attribute will be set at the creating time, and not reevaluated later. This is because you have defined it assigning the value.
How to fix it:
public class kingClass
{
public static void main(String[] args)
{
//fix the first error: set and calculate at the very same object
workClass mClass=new workClass();
mClass.setX(10);
System.out.println(mClass.getX());
mClass.setY(5);
System.out.println(mClass.getY());
System.out.println(mClass.addNum());
}
}
And:
public class workClass extends masterClass {
public int addNum() {
//fix the second point: don't save the value, but recalc every time you need with the actual current value of x and y
return getX()+getY();
}
}
mClass and wClass are 2 different objects.
Also the addition happens during object creation so 10 and 5 don't get added.
So you need to make modifications to kingClass and also workClass.
class kingClass
{
public static void main(String[] args)
{
workClass wClass=new workClass();
wClass.setX(10);
System.out.println(wClass.getX());
wClass.setY(5);
System.out.println(wClass.getY());
System.out.println(wClass.addNum());
}
}
class workClass extends masterClass
{
public int addNum() {return getX()+getY();}
}

How to access public constant variables of main class from a sub class?

I have a main class with a couple of public constant variables, and I have a custom class, I would like to know how can I access the constants of the main class from the custom class?
Main Class code:
import processing.core.*;
import toxi.geom.*;
import toxi.math.*;
public class VoronoiTest extends PApplet {
// this are the constants I want to access from the Site class
public static int NUM_SITES = 8;
public static int SITE_MAX_VEL = 2;
public static int SITE_MARKER_SIZE = 6;
Site[] sites;
public void setup() {
size( 400, 400 );
sites = new Site[NUM_SITES];
for ( int i = 0; i < sites.length; i++) {
sites[i] = new Site( this );
}
}
}
And this is the Site class code:
import processing.core.*;
public class Site {
PApplet parent;
float x, y;
PVector vel;
int c;
Site ( PApplet p ) {
parent = p;
// here I try to get the constants from the main class
vel = new PVector( parent.random(-parent.SITE_MAX_VEL, SITE_MAX_VEL), parent.random(-SITE_MAX_VEL, SITE_MAX_VEL) );
}
}
Any help will be much appreciated!
You can't. Because parent is of type PApplet, not VoronoiTest, you cannot guarantee that it has the static member SITE_MAX_VEL.
Conversely, if parent were of type VoronoiTest, there would be little point in accessing the static variable through the instance, as it would be impossible for it to change.
As already mentioned, to access static members, use the ClassName.STATIC_MEMBER notation (in this case, VoronoiTest.SITE_MAX_VEL).
Better yet though, just store the constants in the Site class instead. After all, that seems the most logical place for them.
import processing.core.*;
public class Site {
public static final int COUNT = 8;
public static final int MAX_VEL = 2;
public static final int MARKER_SIZE = 6;
PApplet parent;
float x, y;
PVector vel;
int c;
Site(PApplet p) {
parent = p;
vel = new PVector(
parent.random(-MAX_VEL, MAX_VEL),
parent.random(-MAX_VEL, MAX_VEL)
);
}
}
Use the VoronoiTest reference. VoronoiTest.SITE_MAX_VEL, for example. When you use a PApplet reference, the compiler doesn't have any way of knowing that the static variables exist.
Static fields are accessed via the class-name. Use VoronoiTest.SITE_MAX_VEL.

Categories