Problem with Classes inheritance in ArrayList - Java - java

I have Card Class, that has several properties:
name
value
isPicked
Card Class
There are also classes that inherit from it, one of them:
Card Class inheritance Class
Next, I created an array, specified the Card Class in generic, and inside I have classes there that are inherited from Card.
enter image description here
But when I try to access the properties of these classes, I get null, since it all refers to Card, and not to the classes that inherit from it. :(
How can i fix it?

you need to cast your object to DaimondCard. Then you will be able to access all properties of DaimondCard. You can see in below program that if we are using ((DiamondCard)card).name) then we will be able to access properties. When you use directly call card.name then it will refer to Card Class.
Daimond card have Age properties which is not part of Card class so if we are using card.age it will give us error.
And to understand this behaviour refer link provided by #Janez Kuhar
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
import java.util.ArrayList;
class Card {
String name;
char value;
Card(){}
#Override
public String toString()
{
return "Card{" + "name='" + name + '\'' + ", value=" + value +'}';
}
}
class DiamondCard extends Card {
String name = "Diamond";
char value;
String age;
DiamondCard(){
}
#Override
public String toString()
{
return "DiamondCard{" + "name='" + name + '\'' + ", value=" + value + '}';
}
}
public class InheritanceDemo
{
public static void main(String[] args)
{
DiamondCard diamondCard1 = new DiamondCard();
diamondCard1.name="card1";
diamondCard1.value='A';
diamondCard1.age = "age";
ArrayList<Card> cards = new ArrayList<>();
cards.add(diamondCard1);
cards.forEach(card -> System.out.println(card.name));
cards.forEach(card -> System.out.println(((DiamondCard)card).name));
cards.forEach(card -> System.out.println(card.age));
cards.forEach(card -> System.out.println(((DiamondCard)card).age));
}
}

Related

Java - incorrect creation of subclasses and super classes

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 + ".";
}
}

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.

i created 2 classes and i want to use Class A in the methode of class B

i created 2 classes and i want to use Class A in the methode of class B
created class A
i use protected because i created a superclass in my code, dont mind it
public class A {
protected String modulname;
protected String verantwortliche;
protected int sws;
protected int credits;
public A ( String modulname, String verantwortliche, int sws, int credits ){//beginning of the methode of class A
this.modulname =modulname;
this.verantwortliche = verantwortliche;
this.sws= sws;
this.credits = credits;
}
public class B {
private String pruefer;
private double leistungeninprozent;
//i want to use the Attributes/Constructors form class A in the class B
//an put it like this:
public B (class A, String pruefer, double
leistungeninprozent){
this.leistungeninprozent = leistungeninprozent;
this.modul = modul;
this.pruefer = pruefer;
}
change this:
public B (class A, String pruefer, double
leistungeninprozent){
this.leistungeninprozent = leistungeninprozent;
this.modul = modul;
this.pruefer = pruefer;
}
to this:
public B (A aObject, String pruefer, double //change "class A" to "A aObject"
leistungeninprozent){
this.leistungeninprozent = leistungeninprozent;
this.modul = modul;
this.pruefer = pruefer;
}
then you can access it in the B constructor like this: aObject.modulname
Beautiful it worked. And how do I implement the toString methode?
I mean implement the toString of class A into the toString of class b.
Thats the toString form class A:
#Override
public String toString() {
return "Module [Modulname=" + modulname + ", Verantwortliche=" + verantwortliche + ", SWS=" + sws
+ ", Credits=" + credits + "]";
}
That is the toString methode from class B:
#Override
public String toString() {
return "Leistungen [Pruefer=" + pruefer + ", LeistungeninProzent=" + leistungeninprozent
+ "]";
}
Now i want to make only one toString methode from the two different classes.
At this very early point in the process of learning Java, I would advise avoiding the use of nested classes. An instance of B can only exist within an instance of class A.
To answer your question, a parameter should represent an instance of a class, not the class itself. Which then becomes a local variable within the method, and through which you can access its fields and methods.

Java Polymorphism How to call to super class method for subclass object

Here is an example of what I am trying to ask
superclass Name.java
public class Name{
protected String first;
protected String last;
public Name(String firstName, String lastName){
this.first = firstName;
this.last = lastName;
}
public String initials(){
String theInitials =
first.substring(0, 1) + ". " +
last.substring(0, 1) + ".";
return theInitials;
}
and then the subclass is ThreeNames.java
public class ThreeNames extends Name{
private String middle;
public ThreeNames(String aFirst, String aMiddle, String aLast){
super(aFirst, aLast);
this.middle = aMiddle;
}
public String initials(){
String theInitials =
super.first.substring(0, 1) + ". " +
middle.substring(0, 1) + ". " +
super.last.substring(0, 1) + ".";
return theInitials;
}
so if i create an Threename object with ThreeNames example1 = new ThreeNames("Bobby", "Sue" "Smith") and then call System.out.println(example1.initials()); I will get B.S.S. I get that.
My question is is there a way to call the initials method that is in the Name class so that my output is just B.S.
no. once you've overridden a method then any invocation of that method from outside will be routed to your overridden method (except of course if its overridden again further down the inheritance chain).
you can only call the super method from inside your own overridden method like so:
public String someMethod() {
String superResult = super.someMethod();
// go on from here
}
but thats not what youre looking for here.
you could maybe turn your method into:
public List<String> getNameAbbreviations() {
//return a list with a single element
}
and then in the subclass do this:
public List<String> getNameAbbreviations() {
List fromSuper = super.getNameAbbreviations();
//add the 3 letter variant and return the list
}
There are many ways to do it. One way: don't override Names#initials() in ThreeNames.
Another way is to add a method to ThreeNames which delegates to Names#initials().
public class ThreeNames extends Name {
// snip...
public String basicInitials() {
return super.initials();
}
}
I would instead leave initials alone in the superclass and introduce a new method that will return the complete initials. So in your code I would simply rename the initials method in ThreeNames to something else. This way your initials method is the same across the implementations of Name

How to retrieve information from one class to another

I have the following code to retrieve information from a text box to another within the same class
btnAddItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String tabno = textArea_TableNo.getText();
String name = textArea_Name.getText();
String size = textArea_size.getText();
String quan = textArea_quantity.getText();
String price = textArea_price.getText();
textArea.append(tabno + ", " + name + ", " + size + ", " + quan + ", " + price + "\n");
But I am not sure how to do this exactly same operation between two class. I probably have to "extend" my class but I've already extended the class to my database class. Im just not sure how else I can do this. Any suggestions to get my head around this would be appreciated..
Well, you can have a public method to retrieve the text, and use this on another class. For example:
class Class1 {
private JTextArea textOne;
//... declare other fields, build GUI, etc
public String getTextOneText() {
return textOne.getText();
}
}
class Class2 {
private JTextArea textTwo;
private Class1 class1;
public Class2( Class1 class1 ) {
this.class1 = class1; //store reference to class1.
}
//use the getData method to append text from the Class1.
void getData() {
textTwo.append( class1.getTextOneText() )
}
}
In this example, storing the reference to the instance of Class1 in Class2 and using the method getData should do what you want.
Another way is use the Observer Design Pattern to communicate between classes.

Categories