I have troubles with method in hereditary classes - java

I have a 2 class, one of which extends the superclass.
when I call the sub-class from the main, I get an error because "the method I call isn't a part of the class", but as my programme goes on, it should work
I had to use it only with the casting of class, but my teacher told me that casting should not be used in such a work, so please I'd like to understand where I'm wrong and where I can do better
(Im providing the code of 3 classes, the sub-class, the super-class, and the main)
Main
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Type in the number");
int number = in.nextInt();
System.out.print("Type in the name");
String name = in.next();
Test testObj = new Test(number);
testObj = new TestSub(number);
testObj.setNameSub(name);
in.close();
}
}
Super class
public class Test {
protected int number;
protected String name;
public Test(int number){
this.number=number;
}
public void setName(String name){
this.name=name;
}
public String toString(){
return "the name is "+name+"the number is "+number;
}
}
Sub Class
public class TestSub extends Test {
public TestSub(int number){
super(number);
}
public void setNameSub(String name){
setName(name);
}
public String toStringSub(){
return toString();
}
}
The error I get is this:
The method setNameSub(String) is undefined for the type Test
In the main where there is this instruction : testObj.setNameSub(name);

The error here is (as indicated in the comments) that you initialize testObj as Test instead of TestSub, causing the error when the compiler isn't able to find setNameSub() between Test's methods.
So the easy solution is clearly to initialize testObj as a TestSub.
The correct solution that takes advantage of the methods inheritance would be to keep the initialization as it is but to call the method testObj.setName(name) instead, and deleting setNameSub() and toString() methods from TestSub class since they don't add any difference from the methods in the Test class.

Related

Java Inheritance: Calling a subclass method in a superclass

I'm very new to java and would like to know whether calling a subclass method in a superclass is possible. And if doing inheritance, where is the proper place to set public static void main.
Superclass
public class User {
private String name;
private int age;
public User() {
//Constructor
}
//Overloaded constructor
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public static void main(String []args) {
User user1 = new Admin("Bill", 18, 2);
System.out.println("Hello "+user1.getName());
user1.getLevel();
}
}
Subclass
public class Admin extends User {
private int permissionLevel;
public Admin() {
//Constructor
}
//Overloading constructor
public Admin(String name, int age, int permissionLevel) {
super(name, age);
this.permissionLevel = permissionLevel;
}
public void getLevel() {
System.out.println("Hello "+permissionLevel);
}
}
Short answer: No.
Medium answer: Yes, but you have to declare the method in the superclass. Then override it in the subclass. The method body from the subclass will be in invoked when the superclass calls it. In your example, you could just put an empty getLevel method on User.
You could also consider declaring User as an abstract class and declaring the getLevel method as abstract on the User class. That means you don't put any method body in getLevel of the User class but every subclass would have to include one. Meanwhile, User can reference getLevel and use the implementation of its subclass. I think that's the behavior you're going for here.
I'm very new to java and would like to know whether calling a subclass
method in a superclass is possible.
A superclass doesn't know anything about their subclasses, therefore, you cannot call a subclass instance method in a super class.
where is the proper place to set public static void main.
I wouldn't recommend putting the main method in the Admin class nor the User class for many factors. Rather create a separate class to encapsulate the main method.
Example:
public class Main{
public static void main(String []args) {
User user1 = new Admin("Bill", 18, 2);
System.out.println("Hello "+user1.getName());
user1.getLevel();
}
}
No, it is not possible to call sub class method inside super class.
Though it is possible to call different implementations of the same method in a client code while you have a variable with a super class type and instantiate it with either super class or sub class objects. It is called polymorphism.
Please, consider the following example:
public class User {
private String name;
private int age;
protected int permissionLevel;
public User() {
//Constructor
}
//Overloaded constructor
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public void getLevel() {
System.out.println("Hello "+ permissionLevel);
}
}
public class Admin extends User {
public Admin() {
//Constructor
}
//Overloading constructor
public Admin(String name, int age, int permissionLevel) {
super(name, age);
this.permissionLevel = permissionLevel;
}
#Override
public void getLevel() {
System.out.println("Hello "+permissionLevel);
}
public static void main(String []args) {
User user1 = new Admin("Bill", 18, 2);
System.out.println("Hello "+user1.getName());
user1.getLevel(); //call to subclass method
user1 = new User("John", 22); //the variable is the same but we assign different object to it
user1.getLevel(); //call to superclass method
}
}
Answering your second question, no, it does not matter where you place your main method as long as it is of right method signature. As you can see in my example I moved the method to Admin.java - it is still acceptable.
Calling subclass method in a superclass is possible but calling a subclass method on a superclass variable/instance is not possible.
In java all static variable and methods are considered to be outside the class i.e they do have access to any instance variable or methods. In your example above it will be wise to create a new class called Main and put public static void main in there but this is just a hygiene issue and what you have above will work except for the line.
user1.getLevel()
Use case: If employee eats, then automatically should sleep:-)
Declare two methods eat and sleep from class person.
Invoke the sleep method from eat.
Extend person in the employee class and override only the sleep method:
Person emp=new Employee();
emp.eat();
Explanation: As eat method is not in subclass, it will invoke the super class eat. From there, sub class's sleep will be invoked.

How to access superclass variables from user input

I am trying to access the super class variable name from user input.
I am not sure how to have the super class variable name point to the user input. Here is the code for it. Any ideas thank you.
package chapter4;
import java.util.Scanner;
public class VetOffice extends Animal {
public VetOffice(int lifeExpectancy, int weight, String name, Character gender, String type) {
super(lifeExpectancy, weight, name, gender, type);
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Please enter name of pet");
//super(name);
//= console.next();
//}
}
}
//}
The thing is you cannot access super class variables in main method. Because it is static method. If you want to access in main() you have to make Animal class name variable to static. Then you can assgin a value directly in main().
Like this:
in Animal class,
static String name;
in VetOffice,
name = console.next();
You can try different ways depending on the thing that you are going to achieve you have to decide,
Is this variable can be declare as static or not? Because static variables common for every object.
Another way you can do this is,
Create getters and setters for Animal class member variables. Then also you cannot access in the main method because also you have to make those methods and variable to static.
As a solution without makinng them static or a new methods even getters and setters in super class you can create default constructor for super class and assign values like below:
If your variable in the super class is private you have to create getters and setters.
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Please enter name of pet");
VetOffice pet = new VetOffice();
pet.name = console.next();
System.out.println(pet.name);
}
Note: create default constructor If it is unnecessary to create object from VetOffice or super class seeing that you have to pass values to constructor.
UPDATE:
According to your comment
If your variable in the super class is private do this:
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Please enter name of pet");
VetOffice pet = new VetOffice();
pet.setName(console.next());
System.out.println(pet.getName());
}
Another way that you asked for in the comment:
Animal class(partialy implemented to show you)
public class Animal {
int lifeExpectancy;
static int weight;
static String name;
Animal(int lifeExpectancy, int weight, String name, Character gender, String type){
this.weight = weight;
this.name = name;
}
public static String getName() {
return name;
}
public static void setName(String n) {
name = n;
}
}
Then in the main method:
Animal.setName(console.next());
System.out.println(Animal.getName());

How to call a method in an abstract class properly

public abstract class Human{
public String name;
public int number
public void getInfo(){
Name = JOptionPane.showInputDialog("Please enter your name: ");
money = Double.parseDouble(JOptionPane.showInputDialog("Please enter amount of money .00: "));
}
public void displayInfo(){
JOptionPane.showMessageDialog(null,"Name: "+name+"\n"+
"Number: "+number);
}
}
public class Student extends Human {
}
public class Teacher extends Human{
}
public class Janitor extends Human{
{
I need help if calling the methods getInfo() and displayInfo() in all 3 classes below. I have tried:
public class Student extends Human{
public Student(){
getInfo();
displayInfo();
}
it works, but it generates a warning saying "problematic call in constructor" I guess it is not the best way to do it.
I also tried:
#Override
public void getInfo() {
}
but if I leave it empty nothing happens. Basically I am trying to call the method in the abstract class in a simple way without needing to type it up in every class.
As already mentioned, you shouldn't call overridable methods in constructors, because if another class overrides this method and invokes the constructor of the superclass, it may try to use values that are not initialized yet, since the overriden method will be invoked. Example:
public class Superclass {
protected int id;
protected void foo() {
System.out.println("Foo in superclass");
}
public Superclass() {
foo();
}
}
public class Subclass extends Superclass {
public Subclass(int id) {
super();
this.id = id;
}
#Override
protected void foo() {
System.out.println("Id is " + id);
}
}
This will print the unitialized value of id, since you first call the constructor of the superclass which invokes the foo method of the subclass.
You can fix this by making your methods final if this suits your case.
You get the warning because it's a good practice not to call overridables in the constructor; since these overridables could try to access member variables that are not initialized yet (== null) .
You shouldn't call overridable functions inside a constructor. check this link

Problems with inheritance JAVA

I have a class
public class Company {
public String b;// boss
public String n;// name
public Company(String boss, String name){
b=boss;
n=name;
}
public void print(){
JOptionPane.showMessageDialog(null, b +n);
}
}
And a class that extends it
public class MB extends Company {
public static String b;// boss
public static String n;// name
private static String p;//product
public MB(String boss,String name,String product){
super(b,n);
p=product;
}
#Override
public void print(){
JOptionPane.showMessageDialog(null,super.b +super.n +p);
}
Class MB when I do print method I get null null and p value. Why is that? Shouldn't b and n be inherited from the class Company. I am new to JAVA so I might have missed something but reading previous questions and JAVA docs I couldn't find the answer. Personally I think the mistake is
public static String b;// boss
public static String n;// name
But cant figure out how to solve it.
In
super(b,n);
you're passing b and n which refer to your static variables which have yet to be initialized and are therefore null. Perhaps you meant to pass boss and name.
in the inherited class Company, you must send super(boss,name) the received parameters and not the null strings defined in class MB

Java print method won't work in class

I am trying to get the print method in my actor class to print the String that was
built in the toString() method. However I keep getting an error. (invalid method declaration, return type required)
public class actor {
private String name;
private String address;
private int age;
public actor(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
public void setName (String name) {
this.name = name;
}
public void setAddress (String address) {
this.address = address;
}
public void setAge (int age) {
this.age = age;
}
public void setFilm () {
}
public String getName () {
return name;
}
public String getAddress () {
return address;
}
public String toString (String name, int age, String address){
return name+" who's "+age+" and lives in "+address;
}
public void print (){
String a = toString();
System.out.println(a);
}
print();
}
I have been trying to get this working for quite a while to no avail.
Here's the two parts to the trouble you're having:
In order to run your program, you have to have a main method.
You have to understand what static and non-static mean.
First, as mentioned by others, you can't just have a method run because it's declared and defined in your class. You actually need to have it called, directly or indirectly, by the main method. The main method is written like this:
public static void main(String[] args) {
// Do Stuff
}
Secondly, you have to understand what static and non-static mean. Which means, you have to understand the difference between classes and objects.
Classes are blue prints. They describe how to build a particular type of object, what properties (or fields) it has, and what methods can be called off of it.
Objects are the actual instances of objects declared by a class. Think of it like this: A class is like the blueprint for a smart car. The objects are the smart cars themselves.
So now, static vs non-static.
Static means that it belongs to the class (the blueprint), rather than to the actual object. The main method, you will notice, is static. It belongs to the class it's declared in, rather than to any instance objects. This means, outside of itself, the main method knows only about the class that it's in, and any other static methods or objects in that class. Things that are not static belong to the actual objects created from the class -- and the main method will know nothing about these actual objects, unless they are created inside of the main method itself.
So, something like this won't work:
public class StuffDoer {
public void doStuff {
System.out.println("Doing Stuff");
}
public static void main(String[] args) {
doStuff(); // Won't work!
// You can't call a non-static, instance method in a static method!
}
}
Instead, you can first create a new instance object of your class inside of the main method, and then call the non-static instance method off of your instance object:
public class StuffDoer {
public void doStuff {
System.out.println("Doing Stuff");
}
public static void main(String[] args) {
new StuffDoer().doStuff(); // This will work,
// because now you have an instance to call the instance method off of.
}
}
This is usually not as good of a choice, but will also work:
public class StuffDoer {
public static void doStuff { //Now, we make this method static
System.out.println("Doing Stuff");
}
public static void main(String[] args) {
doStuff(); // This will work now, because this method is static.
}
}
You're trying to call print() from your class body. Instead, write a main method and print from there:
public static void main(String[] args) {
Actor a = new Actor(...);
a.print();
}
You should have a main function to let the program run, like:
remove the last line print() then create a new file call Main.java, write
package yourPackage // put them into the same package,
main class can call actor class
public class Main{
public static void main(String[] args) {
actor a = new actor();
a.print();
}
}
Why do you need print() method ? You can just use -
Actor a = new Actor(...);
System.out.println(a);
This will implicitly execute toString() method
Ideally you should do this way. Since purpose of toString() method is to give meaningful String representation of an object.
actor actorObj = new actor();
System.out.println(actorObj );
Calling print(); on class body is invalid. Remove following method call.
print();
First off, you should be calling the print() method from somewhere else (main for example). Even with that, you have an error: You are calling the toString() method (with no arguments, which is taken from the Object class). Just remove the arguments from your toString method to override that one. It can see the fields of its own class anyways. With this, you can do something like the following, and take advantage of Java's default toString call:
public static void main(String[] args) {
System.out.println(new Actor("Bob", "410 Main Street", 42);
}
Java does not allow you to call a method in the body of a class as you are attempting to do with the line of code that is print(); You must put the call to print inside another method. For example
public static void main(String[] args) {
actor a = new actor();
a.print();
}
By adding a main method to your class and using the constructor for Actor in that method you create an Author object. On this Author object call print().
TJamesBoone has given a really good answer to give you an understanding of what is really happening. Follow his answer and it will do as you want.
https://stackoverflow.com/a/19981973/1785341
here is your code.. compile and run..
public class actor {
private String name;
private String address;
private int age;
public actor(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
public void setName (String name) {
this.name = name;
}
public void setAddress (String address) {
this.address = address;
}
public void setAge (int age) {
this.age = age;
}
public void setFilm () {
}
public String getName () {
return name;
}
public String getAddress () {
return address;
}
#Override
public String toString (){
return name+" who's "+age+" and lives in "+address;
}
public void print (){
//String a = toString();
System.out.println(this);
}
public static void main( String[] args )
{
actor a = new actor( "xyz","abc",20 );
a.print();
}
}
Simple as it is....
Once you write toString() method in a class then do another method called print() and call inside the print() method toString() method.
public void print()
{
System.out.println(toString());
}

Categories