Inheritance, deriving from a derived class - java

I am trying to create a class from a class that is already derived from another class. (bit confusing) It adds one extra attribute in the newest "PricedApt" class that is "price". The desired constructor call is as follows
PricedApt p = new PricedApt("jill", 900, true, "jack", 1050.00);
The class is missing its constructor and im trying to create it but not sure whats wrong.
This is the (already derived (2nd) class)
public class RentalApt extends Apartment{
private String tenant;
private boolean rented;
public RentalApt(String owner, int size, boolean rented, String who){
super(owner,size);
tenant = who;
this.rented = rented;
}
My code for the (3rd) class that I have attempted is
public class PricedApt extends RentalApt {
private double price;
public PricedApt(String owner, int size, boolean rented, String who, double priceTag) {
super(owner,size,who);
price = priceTag;
}
}
Can anyone point me in the right direction as to what I am doing incorrectly? The compilation error I'm receiving is cannot find symbol (line 2 column 3).

For one, RentalApt has a four-argument constructor, but its subclass PricedApt is calling super() with only three arguments.
Try changing
super(owner,size,who);
to:
super(owner,size,rented,who);

Related

If Downcasting Should Be Avoided, What Should I Do?

have the following interface class:
public interface IGameObject {
String gameObjectID();
String gameObjectName();
void isActionValid(String action);
void viewActions();
}
I have the following abstract class that implements the above interface.
package gameprobjectpackage;
public abstract class Weapon implements IGameObject {
//Left out getters/setters to keep it simple
private String gameOjectID;
private String gameObjectName;
private int damage;
public Weapon(String gameOjectID, String gameObjectName,int damage) {
super();
this.gameOjectID = gameOjectID;
this.gameObjectName = gameObjectName;
this.damage = damage;
}
I've come across a few posts that suggest downcasting should be avoided. I understand why, BUT, my question is what do I do if I need to access a method that is specific to a sub class. For example:
public class ChargeGun extends Weapon {
private String [] chargeGunActions;
public ChargeGun(String gameOjectID, String gameObjectName, int damage) {
super(gameOjectID, gameObjectName, damage);
chargeGunActions = new String [3];
chargeGunActions[0] = "Charge and Fire";
chargeGunActions[1] = "Release";
chargeGunActions[2] = "Drop Gun";
}
//This method is only meant for gun, and this type of gun is the only one in my game.
//This method, I don't belive should be in the abstract method weapon, because NOT every weapon is a gun.
public void reloadGun()
{
}
I store in in an interventory hashmap like so:
Map<String,IGameObject> inventory = new HashMap<String,IGameObject>();
When I retrieve it, I will get an IGameObject, how do I properly cast it, so that I can access the method in ChargeGun?
You can use the visitor pattern which frees you from casting. The idea is simple : You have an inventory of IGameObject which would have a method accept(GameObjectVisitor v) which directly calls v.visit(this). In your GameObjectVisitor, you just have to implement visit methods for each implementations : For example visit(Chargegun g), visit(Sword s), etc...
To explain it another way, it's like the principle of a boomerang : The GameObjectVisitor calls item.accept(this), and the Item implement accept(GameObjectVisitor g) with a simple g.visit(this).
By doing this, the Visitor has multiple visit methods for each implementation and can do specific stuffs without having to cast/using instanceof.

Java Factory pattern - How to prevent anonymous subclasses

I'm doing a school assignment where I have to implement the Factory pattern. I have come a long way, but there is one last thing I have not been able to get working.
I have the following classes:
//Human.java
package human;
public abstract class Human{
public static Human create(String namn, String pnr){
char nastsist_char = pnr.charAt(9); // takes second last char in pnr
String nastsist_string = Character.toString(nastsist_char);
float siffra = Float.parseFloat(nastsist_string); //Converts to float
if ((siffra % 2) == 0){ //Checks if even
return new Woman(namn, pnr);
}
else{
return new Man(namn, pnr);
}
}
}
//Man.java
package human;
class Man extends Human{
private final String pnr;
private final String namn;
protected Man(String n, String p){
namn = n;
pnr = p;
}
public String toString(){
return "My name is "+namn+" and I am a man.";
}
}
//Woman.java
package human;
class Woman extends Human{
private final String pnr;
private final String namn;
protected Woman(String n, String p){
namn = n;
pnr = p;
}
public String toString(){
return "My name is "+namn+" and I am a woman.";
}
}
I also have a class called Test.java. Here comes my problem: In Test.java, I want to make it impossible to do the following:
Human h = new Human(){};
i.e., to create an anonymous subclass of Human. Unfortunately, this line of code runs just fine, and an anonymous subclass is created. How can I make this line of code unexecutable/uncompilable?
PS. I have already tried making Human final. It was not allowed to combine final with abstract in a class.
EDIT:
So I got the tip to make the Human constructor protected. Here's what it looks like after the change:
//Human.java
package human;
public abstract class Human{
protected Human(){}
public static Human create(String name, String idNumber){
char secondlast_char = idNumber.charAt(9); // takes second last char in pnr
String secondlast_string = Character.toString(secondlast_char);
float siffra = Float.parseFloat(secondlast_string); //Converts to float
if ((siffra % 2) == 0){ //Checks if even
return new Woman(name, idNumber);
}
else{
return new Man(name, idNumber);
}
}
}
Unfortunately, I still do not get an error neither when running or compiling the code of Test.java, which by the way looks like this:
import human.*;
public class Test{
public static void main(String[] args){
Human h = new Human(){};
}
}
Add a constructor with the default visibility:
public abstract class Human {
Human(){}
}
By default this only allows access to classes within the same package so it is known as "package private".
Use the default modifier for constructors:
Human(){}
Please note that making it impossible to create anonymous classes from your base class is not the main problem with your implementation of the Factory Pattern. The pattern's intention is to encapsulate object creation logic, so that it can be changed easily without affecting the classes that are being instantiated nor the clients that use those instances.
Putting a static factory method into a base class that creates concrete instances of its sub classes defeats the objective of class separation thanks to inheritance as well as the purpose of the factory pattern.
I would seriously consider sticking your factory method into a separate class, e.g. HumanFactoryImpl and provide a corresponding interface.

"Constructor Album in class Album cannot be applied to different types"

I'm currently having difficulty getting my new subclass to compile:
public class CompilationAlbum extends Album {
private String seriesOfAlbums;
public CompilationAlbum(String seriesOfAlbums) {
this.seriesOfAlbums = seriesOfAlbums;
albumType = "Compilation";
}
}
Can anyone point out what I'm doing wrong? The fault seems to lie with the constructor, but I can't see why that should cause an error. The error message also reads "actual and formal argument lists differ in length."
EDIT: The Album class, minus methods, looks like this:
import java.util.ArrayList;
public class Album {
private String name;
private ArrayList<Track> trackList;
private int length;
private int fileSize;
private double averageRating;
private String albumType;
public Album(String name){
this.name = name;
trackList = new ArrayList<Track>();
}
If you don't explicitly call a constructor of the superclass in the first line of the subclass constructor, a call to super() is inserted by the compiler. Since Album doesn't have a no-argument constructor, compilation fails because the inserted call to super() isn't valid.
There are two ways to resolve this - either call the existing superclass constructor with some String argument (you'd have to decide what makes sense for your particular use case), or add a no-argument constructor to the superclass (again, the behavior of this constructor will depend on what you're actually trying to do).
Here's an approach that might make sense:
public class CompilationAlbum extends Album {
private String seriesOfAlbums;
public CompilationAlbum(String name, String seriesOfAlbums) {
super(name);
this.seriesOfAlbums = seriesOfAlbums;
albumType = "Compilation";
}
}
Without seeing the source code for Album, I'm guessing that it does not have a default constructor.
You wrote this:
public class CompilationAlbum extends Album {
private String seriesOfAlbums;
public CompilationAlbum(String seriesOfAlbums) {
this.seriesOfAlbums = seriesOfAlbums;
albumType = "Compilation";
}
}
You want this:
public class CompilationAlbum extends Album {
private String seriesOfAlbums;
public CompilationAlbum(String seriesOfAlbums) {
super(seriesOfAlbums);
this.seriesOfAlbums = seriesOfAlbums;
albumType = "Compilation";
}
}
Now that I see the Album class, your problem is private members. Make those protected so child classes can get at them, too.

EnumMap with LuaJava (attempt to call a nil value)

As the title says, I have problem with LuaJava and EnumMap. I'm trying to do a RPG Library, so we have a Character with some Attributes and a list of them. In the code below, I'll report only important things.
I have a class called ConcreteAttribute that extends AbstractAttribute, that has a constructor with a String and two int.
public abstract class AbstractAttribute {
protected String name;
protected int baseValue;
protected double baseMolt;
public AbstractAttribute(String name, int valoreBase, double moltBase){
this.name = name;
this.baseValue = valoreBase;
this.baseMolt = moltBase;
}
/*Getters and Setters*/
}
Then I have an Enum called StatType, that represents the stat you have in RPG games:
public enum StatType {
HP, MP, Attack, Defense;
}
I have also a class called PlayableCharacter, that has (I'll report only important things):
public abstract class PlayableCharacter extends Character{
protected EnumMap<StatType, ConcreteAttribute> statistiche;
//Constructor
public EnumMap<StatType, ConcreteAttribute> getStatistiche(){
return statistiche;
}
and a "put" method from Map.
To create a new character, I'm currently doing this ("Eroe" extends PlayableCharacter):
public static void main(String[] args) {
PlayableCharacter pers = new Eroe("Eroe 1");
ConcreteAttribute atk = new ConcreteAttribute("Attacco", 20, 0);
pers.getStatistiche().put(StatType.Attacco_Fisico, atk);
}
and works fine, but I don't think it is the best solution when you have a lot of ConcreteAttribute and a lot of Character. So I was thinking to use Lua to create "concrete" istance of Character, this way (little example):
-- Eroe 1.lua
function create(eroe)
eroe:setName("Eroe 1")
attributes = luajava.bindClass("personaggi.attributi.StatType")
attacco = luajava.newInstance("personaggi.attributi.ConcreteAttribute", "Attacco", 20, 0)
eroe:getStatistiche():put(attributes.Attacco_Fisico, attacco)
end
but I get this error: PANIC: unprotected error in call to Lua API (attempt to call a nil value). The problem is with the last line, but I'm really new to Lua and I don't even know if Lua can handle EnumMap.
Any solution to this?
Thanks to all and sorry for my bad English ^^
EDIT: I've edited the code, I found an error
An enum constant is public member of its enum class, but you are accessing it like a method using :.
So instead of attributes:Attacco_Fisico you need to use attributes.Attacco_Fisico.

how do I pass subclass parameters into the superclass private variables?

I am confused on how to get parameters from new object instances to also flow into the super class to update the private fields in teh super class.
So I am in an advanced Java class and I have homework that requires a "Person" Super Class and a "Student" subclass that extends Person.
The Person class stores the student name BUT it is the Student class constructor that accepts the Person name.
assume no method in Person to make a variable method update...like subClassVar = setSuperClassVar();
EX:
public class Person
{
private String name; //holds the name of the person
private boolean mood; //holds the mood happy or sad for the person
private int dollars; //holds their bank account balance
}
class Student extends Person //I also have a tutor class that will extend Person as well
{
private String degreeMajor //holds the var for the student's major they have for their degree
Public Student(String startName, int startDollars, boolean startMood, String major)
{
degreeMajor = major; // easily passed to the Student class
name = startName; //can't pass cause private in super class?
mood = startMood; //can't pass cause private in super class?
dollars = startDollars; // see above comments
// or I can try to pass vars as below as alternate solution...
setName() = startName; // setName() would be a setter method in the superclass to...
// ...update the name var in the Person Superclass. Possible?
setMood() = startMood; // as above
// These methods do not yet exist and I am only semi confident on their "exact"...
// ...coding to make them work but I think I could manage.
}
}
The instructions for the homework were a bit vague in terms of how much changing to the superclass of Person I am allowed to make so if you all believe a good solid industry accepted solution involves changing the superclass I will do that.
Some possible examples I see would be to make the private vars in Person class "protected" or to add setMethods() in the person class and then call them in the sub class.
I am also open to general concept education on how to pass subclass contstructor parameters to a super class...and if possible do that right in the constructor portion of the code.
Lastly, I did search around but most of the similiar questions were really specific and complicated code....I couldnt find anything straight forward like my example above...also for some reason the forum post did not clump all of my code together so sorry for the confusing read above.
Thanks all.
First, you need to define a constructor for Person:
public Person(String startName, int startDollars, boolean startMood)
{
name = startName;
dollars = startDollars;
mood = startMood;
}
Then you can pass data up from the Student constructor using super(...):
public Student(String startName, int startDollars, boolean startMood, String major)
{
super(startName, startDollars, startMood);
. . .
}
Alternatively, you can define setters in the Person class and invoke them from the Student constructor.
public class Person
{
private String name; //holds the name of the person
private boolean mood; //holds the mood happy or sad for the person
private int dollars; //holds their bank account balance
public void setName(String name) {
this.name = name;
}
// etc.
}

Categories

Resources