Ok, I have 2 classes that need to inherit from another class..
When I move id fields over it says that it cannot access that fields as it is private. so I call the public get method... but it still doesnt work. What I need to do is move all field into vehicle and make taxi + shuttle to inherit from it
public class Vehicle
{
// A unique ID
private String id;
// The destination
private String destination;
// The location of this taxi.
private String location;
/**
*Constructor for vehicle
*/
public Vehicle(String id)
{
this.id=id;
}
Change the Vehicle's constructor so that it takes an int argument, which you then assign to the classes id field
public Vehicle(int id) {
this.id = id;
}
Now, you'll be required to call super(int ) in of your child classes, which will set the id field
public Taxi(String base, String id){
super(id);
//...
}
ps- I have no idea what this is trying to do, but it doesn't do anything...
public void ID(){
Vehicle id= new Vehicle();
id.getID();
}
And given the fact that we've changed the constructor, it will no lager compile...
public class Vehicle
{
// A unique ID
private String id;
// The destination
private String destination;
// The location of this taxi.
private String location;
/**
*Constructor for vehicle
*/
public Vehicle(String id)
{
this(id, null);
}
/**
*Constructor for vehicle
*/
public Vehicle(String id, String location)
{
this.id = id;
this.location = location;
}
/**
* Returns ID.
*
*/
public String getID()
{
return id;
}
public String getDesitnation() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getLocation() {
this.location = location;
}
public void setLocation(String location) {
this.location = location;
}
}
public class Taxi extends Vehicle
// Whether it is free or not.
private boolean free;
/**
* Constructor for objects of class Taxi.
* #param base The name of the company's base.
* #param id This taxi's unique id.
*/
public Taxi(String base, String id)
{
super(id, base);
free = true;
}
}
public class Shuttle extends Vehicle
{
// The circular route of this shuttle.
private ArrayList<String> route;
// The destination number in route that the shuttle is
// currently headed for.
private int destinationNumber;
/**
* Constructor for objects of class Shuttle
* #param id This shuttle's unique id.
* #param route The route taken by this shuttle.
* The first entry is the starting location.
*/
public Shuttle(String id, ArrayList<String> route)
{
super(id);
this.route = route;
}
}
The attributes declared as private can not be accessed from a subclass. Either declare them as protected or create a constructor in the superclass that assigns them, and call that constructor from the subclass' constructor using super().
When i move id fields over it says that it cannot access that fields as it is private.
This word already tells you what restrict from inheritance.
In Java, every class can have totally private data in it, the key word private symbol the data that only this class can have, even you extends from it, those inherited class still can not use private field.
To utilize inheritance advances in Java but still do not want be accessed by class out of your package, you need to make it protect rather than private scope, hence those member fields would be inherited from base class.
You have more than one problem here, here's what I can see as an issue with your code:
1) I'm assuming that both your code for Vehicle and Taxi are in separate class files. Multiple classes in one file can happen but is a bad practice.
2) id is not accessible for two reasons. The first is because you did not call super(). When extending a class, the first thing you have to do is call the super() class to grab all of the parent's variables. The second is because you've given it private access. Private means it is visible only to the Vehicle class. You can fix this two ways. The first is to change the visibility to something other than private. The second is to create getter and setter methods inside the Vehicle class that allow you to change id from other classes when using the setter.
3) The lines:
location = base; destination = null; free = true;
What is location? What are base, destination, and free? These will also cause errors, you need to declare these variables first as instance variables before your constructor.
Hope this helps!
Related
I'm trying to set up a simple set of classes in Java in such a way that a specific Trader class (see below) can 'talk' to other Robot class objects, as identified by a customer id, and set an offer variable within it.
My intial attempt fails because I've defined customer as a String, which is why customer.receiveTender(target) won't work. But I also tried Agent and the Customer subclass but they don't work.
I'm very new to Java - can someone point me in the right direction?
public class Trader extends Robot {
private String target;
public String selectTarget(String target) {
target = target;
}
public void issueOffer(String target, String customer) {
customer.receiveOffer(target);
}
}
UPDATE:
public class Robot {
private String id;
public Robot() {
id = "No name yet";
}
public void setID (String newID) {
id = newID;
}
public String getID() {
return id;
}
}
public class Customer extends Robot {
private String target;
public void receiveOffer(String target) {
target = target;
}
}
Because, receiveTender() is not a member of String class.
Below line of code means an object with name customer, which is String type has method receiveTender and takes argument as String i.e. target. But, if you look at the String class, it doesn't have any method with name receiveTender and that's the reason. It won't compile.
customer.receiveTender(target);
As per your updated code, receiveOffer is a member of Customer class, which means you need to have instance of Customer class to access its method and that means it should be
public void issueOffer(String target, Customer customer) {
customer.receiveOffer(target);
}
Majority of the times, one class can speak to another class only when the class has an object of another class. Inheritance come into picture for "is a" relationship. The Trader class written above will only make sense if Trader is a Robot otherwise create two separate classes as Robot and Trader.
I am writing a program with different classes and there there is a collection class which will store only the sub-classes of the superclass.
Okay, so i have an Order super class that stores quantity. The code snippet is like this:
abstract class Order { //superclass
private int quantity; //instance variables
public Items(int quantity) { //constructor
this.quantity = quantity;
}
public int getQuantity() { // instance method
return quantity;
}
public abstract double totalPrice();
Then i have sub-classes of the order class. The sub-classes are below.
class Coffee extends Order { //subclass
private String size; //instance variables
public Coffee (int quantity, String size) { //constructor
super(quantity);
this.size = size;
} //... some other methods
} // end of Coffee class
class Donuts extends Order { //sub-class
private double price; //instance variables
private String flavour;
public Donuts(int quantity, double price, String flavour) { //constructor
super(quantity);
this.price = price;
this.flavour = flavour;
} //...some other methods
} //end of donut class
class Pop extends Order {
private String size;
private String brand;
public Pop(int quantity, String size, String brand) {
super(quantity);
this.size = size;
this.brand = brand;
} //...again there are some other methods
} //end of pop sub-class
Now this is where i need help. I have written a collection class that contains ArrayList<>. The code snippet is this:
class OrderList {
private ArrayList<Order> list;
public OrderList() {
list = new ArrayList<Order>();
}
What i want to do in the collection class is to have instance methods that ensure that only sub-classes are only added to my collection class.*
What i have tried so far is this (which makes me a complete fool, i know that).
public void add(Coffee cof) {
list.add(cof);
}
public void add(Donut don) { // i know we cant have methods with the same name
list.add(don);
}
public void add(Sandwich sand) {
list.add(sand);
}
public void add(Pop p) {
list.add(p);
}
SO community can you please give me some hints on my problem.
You are getting your abstractions wrong. A Product .. isn't an Order.
A Product is simply a Product. It has some "identity", and probably different "flavors". But when you think about it, initially, it is not an order. An order comes into existence when a customer selects various products, puts them into some shopping card ... and hits the "order" button.
Just think how things are "in the real" world. And that is what should guide the model that you build.
Meaning: your Products should not subclass Order. Instead, you could be doing something like:
public abstract class ShopItem {
// that contains those things that all products in the shop have in common, like
public abstract double getPrice();
...
and then all your Products extend that class. It might be even more useful to avoid inheritance here completely, and turn ShopItem into an interface (that would depend if you really find good reasons to use an abstract class; in order to define common behavior of ShopItems).
Next:
public class ProductOrder {
private final ShopItem orderedItem ...
private final int quantity ...
And to bring things together:
public final class Order {
private final List<ProductOrder> allItemsOfAnOrder ...
Your method signature will be:
public void add(Order order){
...
}
because an Order can hold reference to any of its subtypes.
I don't really see the need for your own OrderList. Since Order is an abstract class, you can only add instances of non-abstract child classes to any List<Order> that you declare.
Also, instead of
class OrderList {
private ArrayList<Order> list;
public OrderList() {
list = new ArrayList<Order>();
}
}
you can also use
class OrderList extends ArrayList<Order> {
public OrderList() {
super();
}
}
and then simply use the add(Order element) that you inherited from your parent class.
But then again, it might be more convenient to just declare an ArrayList<Order> wherever you intended to use your OrderList, as long as you don't add any new methods (that are not given by a regular List) to justify having an extra class.
I am wondering how do you access an argument created in a different class?
What I have:
public class Card {
private final int cardNumber;
private String cardName;
private final String cardOwner;
private final boolean isCredit;
private double balance;
public Card(int cardNumber, String cardName, String cardOwner, boolean isCredit, double balance) {
this.cardNumber = cardNumber;
this.cardName = cardName;
this.cardOwner = cardOwner;
...
}
I want to access the argument cardOwner in the following way:
public void add(Card[] newCards) {
if (cardOwner == owner) {
...
}
}
but I am not sure on how to go about doing that?
You can't access arguments outside the method they're in. Full stop.
What you can do is access the fields (which in your code have the same name as the constructor arguments. I recommend not giving different things the same name until you understand them well).
If you want to access the field cardOwner from inside the Card class, you can just use its name.
If you want to access the field cardOwner from outside the Card class, you will first need to decide which card you want to get the owner of. If you have a reference to a card (call it card), then you can use card.cardOwner to get that card's owner.
However, private members (fields/methods/constructors) can only be accessed from within the same class (that is the entire point of private). You could either make the field public instead, or add another way to access the field's value, such as a small public method:
public String getCardOwner() {
return cardOwner;
}
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.
I have a facade engine with a method
getOwner()
I also have another class called Car and another caller Owner. Car class also has a getOwner() method while the Owner class contains the name, the cost of the car and the budget of the owner.
So I have a method to initialize the engine and this calls the constructor in the newCARengine class.
public static void iniEngine(String name, int cost) {
model = new newCARengine(name, cost);
}
Composition. The engine class has a car, and the car class has an owner. For me to successfully call the getOwner() method I need to use instance variables (class level variable) to hold a reference to the other object in order to call that method from that object.
MY ENGINE CLASS: [below]
public class engine{
private String name;
private int cost;
public Car car;
public engine(String name, int cost){
this.name = name;
this.cost = cost;
}
public Owner getOwner(){
return car.getOwner();
}
}
I'm referencing the Car class by using an instance variable for that class "public Car car;" which then allows me to use "car.getOwner();" method.
MY CAR CLASS: [below]
public class Car{
public Owner owner //instance variable to reference the owner class
public Owner getOwner(){
return owner;
}
}
Now i'm ready to go to the Owner class where the Owner object is created.
MY OWNER CLASS: [below]
public class Owner{
private String name;
private int cost;
private int budget;
public Owner (String name, int cost){
this.name = name;
this.cost = cost;
}
public Owner (String name, int cost, int budget){
this.name = name;
this.cost = cost;
this.budget = budget;
}
public String getName(){return name;}
public int getCost(){return cost;}
public int getBudget(){return budget;}
}
Now I am doing something wrong as when I run the iniEngine() method, I get a nullpointer exception and this I belive is a result of the object not being created. The error is generated from here:
return car.getOwner(); //from the ENGINE CLASS
I need to return an object as a result of my engine class. but the object is not getting created. Any assistance would be appreciated.
I reviewed your code several times. I don't understand where you associate an owner to a car.
This is what causes the NullPointerException
I suggest you provide a CTOR to Car that gets Owner as parameter and in addition, consider having a setCar method.
Consider using the following code for Car:
public class Car{
public class Car(Owner owner) {
this.owner = owner;
}
private Owner owner //instance variable to reference the owner class
public void setOwner(Owner owner) {
this.owner = owner;
}
public Owner getOwner(){
return owner;
}
}
Style note: in Engine, car should probably also be private, just like the other fields, with either a setter, or a constructor argument.
It seems like some of the fields are not getting set. One debugging "trick" I use in similar cases is to temporarily make the fields final, and see what the compiler complains about. For example, if anybody is setting engine.car, it would complain. In this case, that is a good thing - it should be complaining! And, if nobody is setting engine.car, that's a red flag as to where the NPE is coming from.
Alternatively, if you do have setters/getters, put breakpoints in them (or, if you prefer, add System.out.prints) to verify that they are getting called. Or, temporarily rename them (I add "xxx" to the beginning) to verify that the compiler complains, proving that somebody is calling them.
I never instantiated the objects and only delcared the variables.
By changing the constructor to
public Engine(String name, int cost) {
car = new Car(new Owner(name, cost));
}
This created the objects successfully which in turn allowed me to call the getOwner() method and not get any NullPointerExceptions. Must have missed this part somehow.