Problems with inheritance JAVA - 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

Related

I have troubles with method in hereditary classes

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.

Java Generics - how to access subclass parameters

My sample code structure is like this. There is one parent class Building and one subclass House.
Buiding
public class Building {
private String name;
private int noOfHouses;
}
House
public class House extends Building {
private String houseNumber;
}
I want to write a generic method so that i can access the subclass method also.
something like this.
public <T> void construct(T a){
System.out.println(a.getHouseNumber());
}
Please help.
In fact your example does not show the need of generics. You can use:
public static void construct(House a){
System.out.println(a.getHouseNumber());
}
The same thing, unnecessarily complicated to use generics would also work fine:
public static <T extends House> void construct(T a){
System.out.println(a.getHouseNumber());
}
You can't, and shouldn't do that. It's a bad idea to make parent classes aware of child classes' own concrete methods.
You can use a bounded parameter, if this method is in House, or any other class that doesn't complicate the parent/child relationship:
public static <T extends House> void construct(T a){
System.out.println(a.getHouseNumber());
}
The same thing can be done if the parent is abstract, as suggested above:
public abstract class Building {
private String name;
private int noOfHouses;
public abstract String getHouseNumber();
public static <T extends Building> void construct(T a){
System.out.println(a.getHouseNumber());
}
}
Note that the parent doesn't have to be abstract, as long as it's OK with your design
Generics have nothing to do with this problem. Java provides you with the facility of RunTimePolymorphism, but you can't invoke child's specific method using parent reference.
Consider the following case:
Building b = new House(); //Fine
b.getHouseNumber() // Compiler will be happy only if getHouseNumber is in Building.
I agree with Ernest Kiwele, but if you want to access a method that will be part of a subclass you can override a method in each subclass
abstract class Building{
private String name;
private int noOfHouses;
public abstract String getHouseNumber();
public void construct(){
System.out.println( getHouseNumber() );
}
}
public class House extends Building{
private String houseNumber = "houseNumber";
public String getHouseNumber(){
return this.houseNumber;
}
public static void main(String[] args){
House h = new House();
h.construct();
}
}

Java Abstraction and Interfaces

It's been a rather long time since I've messed around with Java Abstraction and/or Interfaces, but I'm coming back to it now for a project and something is getting on my nerves. Below is a snippet of my code.
public class A {
private static String name = "None";
private static String description = "No description";
public A() {}
public A(User user) {
user.setData(this);
}
public static String getName() {
return name;
}
public static String getDescription() {
return description;
}
}
public class B extends A {
private static String name = "B";
private static String description = "This is B";
public B() {}
public B(User user) {
super(user);
}
}
public class User {
private A a;
public void setData(A a) {
this.a = a;
}
public A getData() {
return a;
}
}
When I use B.getName() I expect it to return "B" but it's instead returning "None".
Now I'm obviously doing something wrong, and searching around didn't help a bit. I'm fairly positive that this is possible someway, unless I'm getting confused with another language.
Could someone please point me in the right direction? Thanks.
You called the getName method on the class B. B doesn't have a static method called getName, so it looks for it in the superclass, A, which does.
Maybe you expect B's version of name to override A's? Variables don't get overridden. A is accessing the static variable name defined on A, that the method was originally called on B doesn't affect that.
Inheritance and static methods don't work well together. OO concepts like polymorphism rely on runtime dispatching, the word static should imply the opposite of that. With polymorphism the program works at a high level of abstraction, referring to the objects by a super type and letting the subclasses work out the details. With static methods you have to refer to the specific subclass you want the method called on, so you don't have that level of abstraction.
Welcome back to Java again.
You are using static variable in class A and B. These variables are associated with class instead of the objects.
If you change your method to get name from the User, it will work as you are expecting.
You need to override the method getName():
public class B extends A {
private static String name = "B";
private static String description = "This is B";
public B() {}
#Override
public static String getName() {
return name;
}
public B(User user) {
super(user);
}
}
The problem you are facing lies in the definition of the methods getName and getDescription: They are defined in class A as static members. This means that even when calling B.getName() the actual call is A.getName() and there the static member variable value of name is set to None.
When thinking about inheritance you have be careful what you declare as static. This has nothing to do with Interfaces or abstract classes.
public class A {
protected String name = "None";
protected String description = "No description";
public A() {}
public A(User user) {
user.setData(this);
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
}
public class B extends A {
public B() {
name = "B";
description = "This is B"
}
public B(User user) {
super(user);
}
}
public class User {
private A a;
public void setData(A a) {
this.a = a;
}
public A getData() {
return a;
}
}
With the protected keyword you can access the fields from the extending class.
See also:
http://www.javatpoint.com/static-keyword-in-java
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
A couple of things to note in your class :
name and description are static variables in both A and B
getName is a static method in A
static variables are bound to the class and static methods can't be overridden
This is the expected behavior since getName() method of class A has access to member variable of its own class that is "name" of class A. It is NOT because of name is static even if you make it non-static and you access it as shown in below code snippet it would return "None". Remember that only methods get overridden not member variables. So "name" of class B is not overriding "name" of class "A".
B b = new B();
System.out.println(b.getName()); --> "None" ("name" is non-static)
----------------------------------------------
System.out.println(B.getName()); --> "None" ("name" is static)
Also, if you want to get "B" as output , override getName() method of class A in class B and make method and variable non-static.

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

How to access a variable which is declared in a method belonging to another Java class?

I have recently started trying my hands at Java and I am stuck at this problem. I have two Java files called Main_file.java and Helper.java. The Helper.java file contains a String variable called the name, which I wish to access form my Mainfile.java and assign to a string variable x. The files look soemthing like this.
Main.java
public class Mainfile{
Helper myhelper =new MyHelper();
public void create_func(){
String x = /* assign the value name from the helper file */;
}
Helper.java
public class Helper{
public void add_name() {
String name = "New_name";
}
}
But this does not seem to work. I am not really sure if the method I am trying is right or wrong. Could somebody please help me? Thank you in advance.
The variable name you create in your Helper class is not class-member but only a member which exists in the method add_name()
If you want a class member you'll have to create it like this:
public class Helper{
String name = "New_name";
}
then you can access it like this:
public class MainFile{
Helper myHelper = new Helper();
public void create_func(){
String x = myHelper.name;
}
}
Many people will say that class-members "have" to be private, so it might be nicer to create getters and setters for the class member:
public class Helper{
private String name = "New_name";
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
}
public class MainFile{
Helper myHelper = new Helper();
public void create_func(){
String x = myHelper.getName();
}
}
You can not directly access a local variable of a method of another class. You can do it by making the method returning the object and access it by calling the method by an object of the class. This is how you can:
public class Mainfile{
Helper myhelper =new Helper();
public void create_func(){
String x = myhelper.add_name();
}
}
public class Helper{
public String add_name(){
String name = "New_name";
return name;
}
}

Categories