Java - incorrect creation of subclasses and super classes - java

First, I think the title of this post could be better, so if you want to edit it feel free to do so (or let me know how you think I should edit it).
I am going over practice problems for Java interviews. I am not interviewing right now, but I think this is the best way for me to find all my weak spots with Java. And before you say it, yes, I am finding I am VERY weak in many areas of Java and that I will need to do lots or review before interviewing.
I have some questions about the following code:
public class VehicleApp {
public static void main(String[] args) {
Ford myFord = new Ford();
System.out.println(myFord.countWheels());
Kawasaki myKawasaki = new Kawasaki(1985, "Eliminator");
System.out.println(myKawasaki.countWheels());
}
}
class Vehicle {
protected String make;
protected int numWheels;
public Vehicle() { }
public String countWheels() {
return "The number of wheels this " + make + " has is " + numWheels + ".";
}
}
class Ford extends Vehicle {
public Ford() {
make = "Ford";
numWheels = 4;
}
}
class Kawasaki extends Vehicle {
private String model;
private int year;
public Kawasaki(int year, String model) {
make = "Kawasaki";
numWheels = 2;
this.model = model;
this.year = year;
}
public String countWheels() {
return "The number of wheels this " + year + " " + make + " " + model + " has is " + numWheels + ".";
}
}
First, I notice that there are no references to super() in the code. I thought that when you are dealing with super classes and subclasses, it was required that the subclass constructor include a reference to the super class constructor in the form of super(); (and including parameters if the super class constructor has them). Yet this code seems to work without them. Am I wrong about this requirement? Am I missing something else in this picture?
Second, the Kawasaki class doesn't include the decoration #Override for the countWheels() method. Since this method has the same name (albeit different parameters) as the super class' countWheels() method, wouldn't it be required to have an #Override decoration? Or is that only if the parameters are the same type and same order?
Thanks!

If you do not explicitly call super() in your derived class, the Java compiler will automatically generate a call to super() for you. But this, of course, only works if the base class constructor takes no arguments. This can be demonstrated by adding a System.out.println("Constructor called."); statement to your otherwise empty Vehicle constructor.
The #Override decorator, as you have found out but have not convinced yourself of, is optional. But it is considered a "best practice" to use this when overriding a method for catching errors if you change the method signature.
The one, hopefully constructive, comment I would make is that since a Vehicle must have attributes make and numWheels, I personally would require that these be specified in the Vehicle constructor. Now there is no possibility of having a derived class with these attributes undefined.
public class VehicleApp {
public static void main(String[] args) {
Ford myFord = new Ford();
System.out.println(myFord.countWheels());
Kawasaki myKawasaki = new Kawasaki(1985, "Eliminator");
System.out.println(myKawasaki.countWheels());
}
}
class Vehicle {
protected String make;
protected int numWheels;
public Vehicle(String make, int numWheels) {
this.make = make;
this.numWheels = numWheels;
}
public String countWheels() {
return "The number of wheels this " + make + " has is " + numWheels + ".";
}
}
class Ford extends Vehicle {
public Ford() {
super("Ford", 4);
}
}
class Kawasaki extends Vehicle {
private String model;
private int year;
public Kawasaki(int year, String model) {
super("Kawasaki", 2);
this.model = model;
this.year = year;
}
#Override
public String countWheels() {
return "The number of wheels this " + year + " " + make + " " + model + " has is " + numWheels + ".";
}
}

Related

extensiv function in Java

I got the follow errors:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
groeße cannot be resolved or is not a field
geschlaecht cannot be resolved or is not a field
groeße cannot be resolved or is not a field
public static void main(String[] args) {
person Emil = new person();
Emil.name = "Emil";
Emil.alter = 22;
Emil.groeße = 18;
Emil.geschlaecht = "maennlich";
System.out.println("Emil: " + Emil + "Alter" + Emil.alter + "Name:" + Emil.name + "Größe" + Emil.groeße);
}
public class person{
public String name;
public byte alter;
}
public class Eigenschaften extends person {
public byte groeße;
public String geschlaecht;
}
I tried to fix it as per other users' comments. Now emil is an Eigenschaften
New error:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
No enclosing instance of type QuizFrage is accessible. Must qualify the allocation with an enclosing instance of type QuizFrage (e.g. x.new A() where x is an instance of QuizFrage).
at QuizFrage.main(QuizFrage.java:5)
public class QuizFrage {
public static void main(String[] args) {
Eigenschaften emil = new Eigenschaften();
emil.name = "Emil";
emil.alter = 22;
emil.groeße = 18;
emil.geschlaecht = "maennlich";
System.out.println("Emil: " + emil + " Alter" + emil.alter + " Name:" + emil.name + " Größe" + emil.groeße);
}
class Person{
public String name;
public byte alter;
}
class Eigenschaften extends Person {
public byte groeße;
public String geschlaecht;
}
}
to be honest, your code would definitely show a compilation error for the code you wrote.
Check out the below code. Make sure to follow the coding standards as the class name Should start with a capital letter.
public class Test {
public static void main(String[] args) {
Eigenschaften Emil = new Eigenschaften();
Emil.name = "Emil";
Emil.alter = 22;
Emil.groeße = 18;
Emil.geschlaecht = "maennlich";
System.out.println("Emil: " + Emil + " Alter " + Emil.alter + " Name: " + Emil.name + " Größe :" + Emil.groeße);
}
}
class Person{
public String name;
public byte alter;
}
class Eigenschaften extends Person {
public byte groeße;
public String geschlaecht;
Eigenschaften(){
}
}
In this case, just need to add a constructor for the subclass which is Eigenschaften and create the object from there. My modifications:
Also Save these three as separate java files
public class PersonDetails
{
public static void main(String[] args) {
Eigenschaften Emil = new Eigenschaften();
Emil.name = "Emil";
Emil.alter = 22;
Emil.groeße = 18;
Emil.geschlaecht = "maennlich";
System.out.println(" Emil: " + Emil + " Alter " + Emil.alter + " Name: " + Emil.name + " Größe " + Emil.groeße);
}
}
class Person {
public String name;
public byte alter;
}
class Eigenschaften extends Person {
public byte groeße;
public String geschlaecht;
public Eigenschaften(){}
}
After that compile these three classes separately according to the order Person.java,Eigenschaften.java and PersonDetails.java
After compiling Run the main class
java PersonDetails
Then you can the resultant output as
Emil: Eigenschaften#15db9742 Alter 22 Name: Emil Gr????e 18
You already got some answers, but I thought I would give you some additional tips.
(1) Class names are always with a capital letter. So you do not have a class person but Person.
(2) In my opinion it is a better way to implement one class per file, so I would create one directory containing a file Person.java only containing the class Person and so on. Of course you can also use inner classes and they can make sense, but not for this beginning code.
(3) NEVER program in german. We have these weird letters ä,ö,ü,ß which are not known in english and can give you some ugly question marks or other unknown symbols when printing on terminal. Also this may lead to some weird effects when accessing fields. So please use english language.
(4) I think you got a wrong understanding of OOP at this point. Eigenschaften (for all native-english people on Stackoverflow: Properties) are not a subclass of person, because it does not make sense. OOP is for example: You have a superclass Animal and then you have subclasses Dog, Cat, Bird and so on. Now all types of animals have the same behaviors. For example they can all speak. A dog barks, a cat mious and a bird does something else :D I don't know the english term for that.
Then you would have a structure like this:
public interface Animal {
public void makeSound();
}
// For example for the dog:
public class Dog implements Animal {
public void makeSound() {
System.out.println("Woof");
}
}
In this case I used an interface. You can also just use a normal or an abstract class. That always depends on your needs.
So in your case you would just have a class person like this:
public class Person {
public String name;
public byte age;
public byte size;
public String gender;
//Constructor, getters, setters, toString
}
(5) And the last improvement:
You do not need to write something like this:
System.out.println("Emil: " + emil + " Alter" + emil.alter + " Name:" + emil.name + " Größe" + emil.groeße);
Just implement a toString-method in class Person. Then you can simplify this command to
System.out.println(emil);
where emil is an object of type Person. The toString method will be used automatically.

How to have a driver class inherit certain attributes of a super class?

I am trying to have my driver class inherit the information from two different classes. I have to use the formula className objectName = new className(input parameters) to instantiate one of the classes. But I keep getting the symbol not recognized error.
I'm not sure how I could fix this problem. I tried creating an import statement, but the other two classes are part of the same package. I have also tried using the extends keyword, but also noluck
public class Corgi extends Dog {
// additional class variables
private static int weight;
private static int age;
// constructor
public Corgi(String type, String breed, String name, int pounds, int years) {
// invoke Dog class (super class) constructor
super(type, breed, name);
weight = pounds;
age = years;
}
// mutator methods
public static int setWeight(int pounds){
weight = pounds;
return pounds;
}
public static int setAge(int years){
age = years;
return years;
}
// override toString() method to include additional dog information
#Override
public String toString() {
return (super.toString() + "\nThe Corgi is " + age +
" years old and weighs " + weight + " pounds.");
}
}
public class Dog {
// class variables
private static String type;
private static String breed;
private static String name;
private static String topTrick;
// constructor
public Dog(){
type = "none";
breed = "none";
name = "none";
}
// methods
public static String setTopTrick(String trick){
topTrick = trick;
return trick;
}
// method used to print Dog information
public String toString() {
String temp = "\nDOG DATA\n" + name + " is a " + breed +
", a " + type + " dog. \nThe top trick is : " +
topTrick + ".";
return temp;
}
}
public class Main
{
public static void main(String[] args) {
Corgi tricker = new Corgi();
tricker.setTopTrick("Backflip");
System.out.println(tricker);
}
}
I am expecting to be able to have the main class inherit Corgi's info with the Corgi tricker = new Corgi(); statement. But I keep getting the error:
Main.java:6: error: cannot find symbol
Corgi tricker = new Corgi("Hunting", "Shiba", "Simon", 30, 7);
^
symbol: class Corgi
location: class Main
In your Corgi class you need to remove variables from super()
public Corgi(String type, String breed, String name, int pounds, int years) {
// invoke Dog class (super class) constructor
super();
weight = pounds;
age = years;
}
2.Then you have to add values in Corgi(); which is in `Main class'
public static void main(String[] args) {
Corgi tricker = new Corgi("puppy", "Husky", "Alex", 15, 1);
tricker.setTopTrick("Backflip");
System.out.println(tricker);
}
output -:
DOG DATA
none is a none, a none dog.
The top trick is : Backflip.
The Corgi is 1 years old and weighs 15 pounds.
Sorry everyone. My code wasn't the problem. I tried using the code in a different compiler and it worked just fine. I did tweak my code a little with Kalana's advice. Thanks everyone.

How to #Override an Attribute declared in an Interface implemented in a class

Interface:
package II_1_b;
public interface Bezeichnung {
public String Bezeichnungi = "Hallo";
public abstract void setBezeichnung();
}
class:
package II_1_b;
public class Speerwurf extends SportDaten implements Bezeichnung {
private double weite;
#Override
public void setBezeichnung(){ //Here we want to Override the String in
Bezeichnungi = "Test"; //the Interface
}
public Speerwurf(String n, double w, String bez) {
super(n);
this.weite = w;
bez = Bezeichnungi;
}
#Override
public void display() {
System.out.println("Speerwurf von " + this.SportlerName + ":\n"
+ weite + " Meter " + Bezeichnungi);
}
}
You can see our Code here, I commented the problem area and hope you can help us. Stackoverflow tells me to add more details, so I'm gonna describe what I'm going to have for lunch: I think I will make myself a TK-Pizza, maybe 2. I'm often very hungry.
String Bezeichnungi inherited from the interface into the class is final and hence cannot be overridden.
As #slaw stated, fields in interfaces cannot be changed and are thus static and final.
Additionally, there is no sense of declaring fields in an interface, because it only declares a certain behaviour and not a state. To make things work like you showed here, you need to use an abstract class:
package II_1_b;
public abstract class Bezeichnung {
public protected String Bezeichnungi = "Hallo";
public abstract void setBezeichnung();
}
Concrete class:
package II_1_b;
public class Speerwurf extends Bezeichnung { //think about how to handle SportDaten!
private double weite;
#Override
public void setBezeichnung(){ //Here we want to Override the String in
Bezeichnungi = "Test"; //the Interface
}
public Speerwurf(String n, double w, String bez) {
super(n);
this.weite = w;
bez = Bezeichnungi;
}
#Override
public void display() {
System.out.println("Speerwurf von " + this.SportlerName + ":\n"
+ weite + " Meter " + Bezeichnungi);
}
}
Since we dont know your concrete use case, we cannot help you except of telling you why it does not work the way it should

UML diagram confusion

Hi guys,this is my first question on StackOverflow
I am kind of new to java and I need to solve this uml diagram .
I got a solution from one of my classmates but I don't think it's correct and I did it my way. My question is which one of the solutions is correct? I know that the type of relation is an association one . Not an inheritance
Her code
class Sensor {
protected int value;
protected String location;
public Sensor() { // default constructor
value = 0;
location = "North-West";
}
public Sensor(int value, String location) { // overridden constructor
this.value = value;
this.location = location;
}
protected int getValue() { // value getter
return value;
}
protected void setValue(int v) { // value setter
this.value = v;
}
protected void displaySenzorInfo() { // display information on the sensor
System.out.println("Temperature is " + value + ", located " + location + ".");
}
}
class Controller extends Sensor {
protected String name;
public Controller(String name) { // overridden constructor
this.name = name;
}
public Controller(String name, int value, String location) { // overridden
// instructor
this.name = name;
super.value = value;
super.location = location;
}
public Controller() { // default constructor, which creates a new Sensor()
//Sensor s = new Sensor();
}
protected void checkTemperature() { // checks temperature of sensor
System.out.println("Temperature of " + name + " is " + super.value + ", located at " + super.location + ".");
}
}
public class E3 {
public static void main(String[] args) {
Controller control = new Controller();
control.displaySenzorInfo();
Controller c = new Controller("Pizza", 30, "North");
c.checkTemperature();
}
}
My code
class Sensor{
int value;
String location;
Sensor(){
value=0;
location="Sibiu";
}
Sensor(int value,String location){
this.value=value;
this.location=location;
}
int getValue(){
return value;
}
void setValue(int v){
this.value=v;
}
void displaySenzorInfo(){
System.out.println("Temperature is " + value + ", located " + location + ".");
}
}
class Controller{
Sensor tempSensor;
String name;
Controller(){
name="Sibiu";
tempSensor=30;
}
Controller (String name,Sensor tempSensor){
this.name=name;
this.tempSensor=tempSensor;
}
void checkTemperature(Sensor tempSensor){
if (tempSensor>=30)
System.out.println("the temperature is too high!");
else
System.out.println("the temp is too low" );
}
}
public class E3{
public static void main(String []args){
Sensor s1=new Sensor();
Controller c1=new Controller();
c1.displaySenzorInfo();
Controller c2=new Controller(30,"Oliver");
}
}
Please guys. If you have some suggestions or if you see any problems in m program tell me. I know that I will have some errors because I didn't work at this exercise in any IDE because I am at work and I don't have any . Thank you!!!
your solution is the correct one. As you mentioned already, it is an association and not an inheritance. You can see how an inheritance looks like on wikipedia: https://en.wikipedia.org/wiki/Class_diagram
Though overall coding (MyCode) for relationship from the given diagram is OK, I have following observations. (Her code) - Inheritance is not correct. Unidirectional association is correct.
If this is diagram is only for exercise purpose its OK, otherwise it will violate data hiding and encourage client classes to violate encapsulation (Using somebody else's data directly)
tempSensor=30;is not correct for data type.
if (tempSensor>=30) is incorrect for data type and even if you correct, it violates encapsulation (works on somebody else's data) as an effect of first violation of making instance variables non-private. classes should work on their own data.
Even if for some reason we accept above violation, checkTemperature(Sensor tempSensor) makes use of fresh instance of Sensor (for every call), which is not the one obtained from association relationship. This method should not have parameter, it should work on this.tempSensor (with accepted data leakage). Ideally this is indication that data and its behavior are getting separated and design needs to be corrected.
In case the diagram can not be changed then just remove the parameter in checkTemperature() and take care of data types as shown above.
But I would suggest change at Design level as follows for better encapsulation.
public class SensorNew {
private static final double UPPER_THRESHOLD = 25;
private static final double LOWER_THRESHOLD = 20;
private String location;
private Controller controller;
public SensorNew(String location, Controller controller) {
this.location = location;
this.controller = controller;
}
public int getCurrentTemp() {
// obtain from sensor hardware
return 10; // Just example
}
private void makePeriodicCheck(){
double currentTemp = getCurrentTemp();
if (currentTemp > UPPER_THRESHOLD){
controller.coolDown();
} else if (currentTemp < LOWER_THRESHOLD){
controller.heatUp();
} else {
controller.stopIfRunning();
}
}
public void displaySenzorInfo() { // replace by toString()
System.out.println("Temperature is " + getCurrentTemp()
+ ", located " + location + ".");
}
}
public class ControllerNew {
private String name;
// Need to maintain the state of Controller
// either by variable or State design pattern (preferred)
public ControllerNew(String name, Sensor tempSensor) {
this.name = name;
}
public void coolDown() {
// action depending upon current state of controller
}
public void heatUp() {
// action depending upon current state of controller
}
public void stopIfRunning() {
// action depending upon current state of controller
}
}
The advantage is that we do not have to provide public getXX() setXX() methods to these classes. Hence it maintains encapsulation.

Undefined Constructor, but I have a default Contructor?

Eclipse says this:
Exception in thread "main" java.lang.Error: Unresolved compilation
problems: The constructor Car(String, String, int) is undefined The
constructor Car(String, String, int) is undefined The method
getCarInfo() is undefined for the type Car The method getCarInfo() is
undefined for the type Car
at CarDriver.main(CarDriver.java:5)
and this is my driver:
public class CarDriver {
public static void main(String[] args) {
Car c1 = new Car("Nissan", "Z31", 175);
Car c2 = new Car("Honda", "Prelude", 145);
System.out.println(c1.getCarInfo());
System.out.println(c2.getCarInfo());
}
}
And this is my class:
public class Car {
/*
* Car class is a method to make a car with make and model of
* String and odometer of int to reflect how fast or how far
* the odometer reads, I guess.
*/
private String make;
private String model;
private int odometer;
public Car() { //This is the default constructor for the Car.
make = "Toyota";
model = "Supra"; //My favorite car, especially the 80s ones. (*•̀ᴗ•́*)و ̑̑
odometer = 225;
}
public Car(String make, String model, int odometer) {
this.make = make;
this.model = model;
this.odometer = odometer;
}
public void setMake(String manufacturer) {
this.make = manufacturer;
System.out.println("The car is made by" + this.make);
}
public void setModel(String type) {
this.model = type;
System.out.println("The car is a " + this.model);
}
public void setSpeed(int speed) {
this.odometer = speed;
System.out.println("The car goes " + this.odometer + " KPH");
}
public String getCarInfo() {
String carDescription = "The car is a " + model + " made by " + make + " and goes " + odometer + " KPH";
return carDescription;
}
}
Not really sure went wrong
Thanks for any help!
Your Eclipse might be confused. Sometimes IDEs get partial builds kind of stuck in memory and can't seem to clear them. I know this sounds like a cop-out, but have you tried tell Eclipse to clean, shutting down Eclipse completely, starting it up again, and tell it to do a full rebuild? I do this when things quit making sense. I've had to do it less since changing IDEs, but it still happens sometimes.
Oh, another possibility (unlikely, but possible): Could you maybe have a compiled earlier version of your classes in a place where Eclipse is picking it up as a library? If you're doing a mix of command-line work and Eclipse work, this could happen. Tell it to ignore any build directories not under its control, and check its imports for anything suspicious.

Categories