Calling a super method in Java - java

Customer.java:17: error: cannot find symbol
super.display();
^
symbol: method display()
1 error
This what is happening when I compile my program. How do I display the objects data in the Customer subclass?
import java.util.Scanner;
public class Person {
private String name;
private String address;
private String number;
//No Argument constructor//
public Person() {
name = "";
address = "";
number = "";
}
//Explicit value constructor//
public Person(String num, String nam, String add) {
number = num;
name = nam;
address = add;
}
//Accessor method//
public String getName() {
return name;
}
//Mutator method//
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephoneNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String toString() {
return name + "\n" + address + "\n" + number;
}
}
The subclass:
public class Customer extends Person {
public Customer(String num, String nam, String add) {
super(num, nam, add);
}
public boolean checkResponse(char response) {
if (response == 'Y') {
return true;
}
return false;
}
public void display() {
super.display();
}
}

In order for super.display() to work, you require a method called display() in your parent class.
Since you have no such method, Java will not allow the code you have to compile.
Since it seems you're trying to show useful information about the object when it's printed, why not override toString() again? The caveat here is that you don't have any more meaningful information to show about it being a Customer over it being a Person (there's no Customer-specific fields, so the inheritance relationship is moot).
You may want to consider adding more info to differentiate a Customer from a Person, then override toString().

The error occurs because there is no display() method in the Person class. So you cant invoke a non existing method using super.display()
So change the display() method in Customer to
public void display() {
System.out.println(super.toString());
}

As the error is trying to tell you, super.display() doesn't exist.

You can simply access the number, name or address directly. Modify the display() method, remove super.display() like below.
public void display()
{
System.out.println("Customer telephone number:" + number);
}

Super keyword in java is related to parent class and Super.display() means you are calling the display method of the parent class.Your parent class is person as you are extending it public class Customer extends Person {
But there is no display() in person hence your are getting compilation error

You don't have display() function defined in parent class(Pesron);

Related

How to print name of object?

What I should change to print the name of chair, which is chairNumber1?
public class Employee {
private Chair s;
Employee(Chair s) {
this.s = s;
}
void showData() {
System.out.println("Name of chair : " + s);
}
}
public class Chair {
}
public class Hlavna {
public static void main(String[] args) {
Chair s = new Chair("chairNumber1");
Employee c1 = new Employee(s);
c1.showData();
}
}
Why when I want to print name of the Chair, which is chairNumber1, Java prints on console the address of chairNumber1, but not it's name?
You must be already aware of the fact that every class in Java inherits a class called Object by default. This class has a method toString() which returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object.
When you use System.out.println("Name of chair : " + s);, it will call s.toString() but since you haven't provided your own implementation of toString() inside class Chair, it will call the toString() method of class Object which is the default superclass of class Chair. This is why you see the value which you think as the address of chairNumber1.
To get your desired String, you need to override the toString() method something like:
public class Chair {
private String name;
public Chair(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
define a method inside your chair class that returns the name or override the toString method.
example:
public class Chair{
private String chairName;
Chair(String chairName){
this.chairName = chairName;
}
public String toString(){
return chairName;
}
}
now inside showdata() call toString():
void showData(){
System.out.println("Name of chair : " + s.toString());
}
There are a couple of things going on here.
You have created a chair object in your main method of your Hlavna class. To this Chair object you have provided an argument, although from the code above Chair does not take an argument.
In the same way that you have made the Employee class take an argument of chair, you should take the Chair take an argument of name, like so:
public class Chair
{
private String name;
Chair(String chairName)
{
this.name = chairName;
}
}
Now this isn't enough. When you print any Java object, under the hood what is really happening is the object's toString method is called. By default this prints the object's address, but you can override that by implementing the method yourself, like so:
public class Chair
{
private String name;
Chair(String chairName)
{
this.name = chairName;
}
public String toString()
{
return this.name;
}
}
Now, when you print a chair object it will call the Chair object's implementation of toString, which here returns the chair's name.
Your employee class is correctly printing the "toString()" method of the chair that you pass to it as you construct it, but currently that looks like an address. If you change the Chair object to the above code, that will instead print the chair name, which is what you are after.
The full code would look like this:
public class Employee
{
private Chair s;
Employee(Chair s)
{
this.s = s;
}
void showData()
{
System.out.println("Name of chair : " + s);
}
}
public class Chair
{
private String name;
Chair(String chairName)
{
this.name = chairName;
}
public String toString()
{
return this.name;
}
}
public class Hlavna
{
public static void main(String[] args)
{
Chair s = new Chair("chairNumber1");
Employee c1 = new Employee(s);
c1.showData();
}
}
public class Chair {
private String name;
public Chair(String name) {
this.name = name;
}
#Override
String toString() {
return name;
}
}

How do I minimize the amount of code for a hierarchy

This is for learning. I have an interface that is implemented by 2 classes, and I am supposed to reduce the amount of code I use in order to keep things more clean and less messy. Currently, the code looks like this:
public abstract class VClass implements IntFace {
protected String name;
public VClass(String name) {
this.name = name;
}
public int value (SClass sc) {//comes from a diff class
return sc.lookup(name);
}
public String getName() {
return name;
}
#Override
public String toString() {
return getName();
}
}
public abstract class NClass extends VClass implements IntFace {
public Number(String name) {
super(name);
this.name = name;
}
public int value (SClass sc) {
return sc.lookup(name);
}
public String getName() {
return name;
}
#Override
public String toString() {
return getName();
}
}
public interface IntFace {
public int value (SClass sc);
public String toString (int num);
}
can this code be more condensed?
You can remove the following things from your code:
implements IntFace from NClass declaration. Since NClass extends VClass, it implements IntFace as well.
this.name = name; from NClass constructor. name is initialized in a superclass constructor
value and getName methods from NClass. These methods are implemented in a superclass.
public modifier from interface methods declaration. Methods in interfaces are public by default.
Now you can also make name field private since it's no longer used in a NClass.

Input doesnt go all the way down to the children

I have a question about this code:
public class Musician {
private String name;
public String instrument;
public Musician(String name, String instrument){
this.name= name;
this.instrument= instrument;
}
public String getInstrument() {
return instrument;
}
public String getName() {
return name;
}
private String getClassName(){
return "Musician ";
}
public void play(){
System.out.println("[M] "+getClassName() + " plays music.");
}
public void printInfo(){
play();
System.out.println("[M] Class name: "+ getClassName());
System.out.println("[M] Instrument: "+ getInstrument());
}
}
public class RockMusician extends Musician{
public String instrument;
public RockMusician(String name, String instrument) {
super(name, instrument);
this.instrument= instrument + " and drums";
}
public String getClassName(){
return " RockMusician ";
}
public void play(){
System.out.println("[RM] "+ getClassName() + getName() + " breaks his "+ super.getInstrument() + "!");
}
}
public class IsraelyRockMusician extends RockMusician {
public IsraelyRockMusician(String name, String instrument) {
super(name, instrument);
}
public String getInstrument() {
return instrument;
}
public String getName(){
return super.getName() + " the king";
}
public String getClassName() {
return " IsraelyRockMusician ";
}
}
public class Testing {
public static void func(Musician m){
System.out.println("I've got a musician!");
}
public static void func(RockMusician m){
System.out.println("I've got a rock musician!");
}
public static void main(String[] args) {
Musician m3 = new IsraelyRockMusician("Chanoch", "guitar");
m3.printInfo();
}
}
I have IsraeliRockMusician who inherits RockMusician who Inherits Musician,
I then make a Musician m3 with the name "chanoch" and instrument "guitar"
and I active the method, print Info,
because the printInfo is in the father -> RockMusician which contains 3 methods on itself-> play(),getClassName(),and getInstrument(),
my question is, when the method showinfo runs, play is going all the way to the overwriten method and prints "[RM] IsraelyRockMusician Chanoch the king breaks his guitar!",
now this is fine, but the next line is "[M] Class name: Musician ", which means the getClassName was given "Musician" and Im asking why its not "IsraeliRockMusician" since the method was overwritten.
I'm sorry if the question is a bit hazey.
The problem is that the method of the base class has private access.
private String getClassName(){
return "Musician ";
}
Change it to public/protected so you can override it.
Instead of having a function where you hardcode the class name, you should use the following:
public class Foo {
public void printClassName() {
System.out.println(this.getClass().getName());
}
}
This way, if you change your class name, you don't need to update the method that you've written. One caveat to this is if you run an obfuscation tool against your code, the class name may be replaced with random characters. In that case, you can create a const string in your class and refer to that instead.

Why do we use Strategy Pattern?

I just learned what the Strategy pattern really is from the Internet. But I wondered how it can improve my code. For example, i have the following codes found in the Internet like this. This is the Superclass named Animal:
abstract public class Animal {
private String name;
private int weight;
private String sound;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
This is the subclass named Dog:
public class Dog extends Animal {
public void digHole(){
System.out.println("Dig a hole");
}
public Dog(){
super();
setSound("bark");
}
public void testSuper(Animal obj){
System.out.println(obj.getName());
}
}
In the tutorial, it said that if we want to add flying ability so that I can check whether dog can fly or not. Adding the code directly like this one is bad as shown in the code below.
The Superclass Animal with an added flying ability method
abstract public class Animal {
private String name;
private int weight;
private String sound;
// Add fly method to the superclass which is a bad idea
public String fly(){
return " I am flying ";
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
Using the Strategy pattern, we can create interface named Flys with the method fly, allowing any subclass to implement the method, thus as shown in the tutorial, I created Interface named Flys with 2 subclasses implementing the interface:
public interface Flys {
String fly();
}
class ItFlys implements Flys{
public String fly(){
return "Flying high";
}
}
class CantFly implements Flys{
public String fly(){
return "I can't fly";
}
}
Once I made the interface, I can refactor the class Animal,
abstract public class Animal {
private String name;
private int weight;
private String sound;
Flys flyingType; // Add an object of the interface to the superclass
public String tryToFly(){ // add a new method tryToFly
return flyingType.fly();
}
// Adding another method named setFlyingAbility
public void setFlyingAbility(Flys newFlyType){
flyingType = newFlyType;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
Now, in my Dog subclass, I simply add another code
public class Dog extends Animal {
public Dog(){
super();
setSound("bark");
flyingType = new CantFly(); // I set flyingType object
}
public void digHole(){
System.out.println("Dig a hole");
}
public void testSuper(Animal obj){
System.out.println(obj.getName());
}
}
The final class is where I can execute all codes, checking whether my Dog class can fly or not.
public class AnimalPlay {
public static void main(String args[]){
Animal sparky = new Dog();
Animal tweety = new Bird();
System.out.println("Dog " + sparky.tryToFly()); // the result is I can't fly
System.out.println("Bird " + tweety.tryToFly()); // the result is I am flying
sparky.setFlyingAbility(new ItFlys());
System.out.println("Dog " + sparky.tryToFly()); // the result is I am flying
}
}
My question is, what about If I still add the fly() method the traditional way, it gives the same result, doesn't it?
Adding the fly() method to the superclass so I can override the fly() method in my Dog class, but this is not a good idea.
abstract public class Animal {
private String name;
private int weight;
private String sound;
// Add fly method to the superclass which is a bad idea
public String fly(){
return " I am flying ";
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
My question is, what about If I still add the fly() method the traditional way, it gives the same result, doesn't it?
The answer is 'NO'.
Strategy pattern allows you to move behavior into separate class which is good by SOLID principle 'S' - single responsibility. Image that you need to learn robot or human to 'bark' - you don't need to make them inherit animal base class. And you also don't need to implement barking in each class.
Having all properties in base class is also not good as it is against SOLID 'L' - Liskou substitution. What if monkey don't need to bark which is implemented in base animal class?
Strategy pattern allows you to design code accordingly to SOLID 'I' - Interface segregation - just make IAnimalAction interface make many implementations of barking and assign IAnimalAction property to desired animal classes (as property or as one more interface to implement)
Strategy also helps with SOLID 'D' - you can inject desired animal strategy (barking, flying) without having each animal even know about it
We can continue and find other bonuses. But you can see a picture
Good luck!
I am not sure which came first, but the Strategy pattern like any other behavioral pattern is a specific instance of the open close principle. In general you want to change the behavior of an object without having to change it's code. This has a profound consequences in terms of extendability, maintainability and coherence.

Overriding a parent class

I have my Pet super class which then has a Dog subclass, and a particular method in my super class is getSpecies(). In my subclass I want to be able to return super.getSpecies(), but also return another variable (in this case, smell) inside that method as well.
Super class:
public class Pet {
protected int lifeSpan;
protected String species, name, interaction;
public Pet(){
}
public Pet(int lifeSpan, String species, String name){
this.lifeSpan = lifeSpan;
this.species = species;
this.name = name;
}
public final float costs(float cost){
return cost;
}
public void setSpecies(String species){
this.species = species;
}
public String getSpecies(){
return this.species;
}
}
Subclass "Dog":
public class Dog extends Pet{
protected String smell;
private String species;
public Dog(String smell){
super(15, "Dog", "Rex");
this.smell = smell;
}
public Dog(){
}
public void setSmell(String smell){
this.smell = smell;
}
public String getSpecies(){
super.getSpecies();
smell = "high"; //Meant to deliberately set it to "High". How am I to return this?
}
public String getSmell(){
return this.smell;
}
}
You cannot return two values in a single function. What you have to do is use your getter for the smell member variable instead.
public class Dog extends Pet{
protected String smell;
private String species;
public Dog(String smell){
super(15, "Dog", "Rex");
this.smell = smell;
}
public Dog(){
}
public void setSmell(String smell){
this.smell = smell;
}
public String getSpecies(){
super.getSpecies();
}
public String getSmell(){
return this.smell;
}
}
Then let's say you want both species and smell, you have to check if the pet is in fact a dog, and if it is, you can safely cast it as a dog and use the specific methods of the Dog class.
if ( pet instanceof Dog ) {
String species = pet.getSpecies();
String smell = (Dog)pet.getSmell();
}
First things first: When calling super.getSpecies() you should save or hand over it's return value somewhere. Then you might consider concatenating this return string an your second return value (high) like this:
public String getSpecies(){
return "high " + super.getSpecies();
}
But:
the return of that high dog doesn't make much sense IMO.
a getter is expected to return only one value, the one it's name comes from.
There is no ather way to return multiple values except for passing objects that take the results as arguements. But that solution would be far away from a simple getter.
You should consider (like Pilibobby pointed out in his comment below) using two different getters in your case, getSpecies() and getSmell(), and combine their results at the place you are calling them from.

Categories

Resources