the requirements are:
Create a file Hop.java with a public class named Hop.
Create two other classes: Skip a subclass of Hop and Jump a subclass of Skip.
Create a no-argument constructor in each of the three classes that prints the name of the class on a line by itself (e.g., use System.out.println(“Hop”) to print the “Hop” class name.
Create a main method (where?) and create a new instance of Jump.
Compile and run. You should see the output Hop, Skip, and Jump printed to standard out. Can you explain it?
and the code I write so far is :
public class Hop {
private String name;
public Hop(String name) {
this.name = name;
}
public static void main(String args[]) {
Jump j = new Jump("Hop", "Skip", "Jump");
System.out.println(j);
}
}
class Skip extends Hop {
private String name1;
public Skip(String name, String name1) {
super(name);
this.name1 = name1;
}
}
class Jump extends Skip {
private String name2;
public Jump(String name, String name1, String name2) {
super(name, name1);
this.name2 = name2;
}
}
This is what the question is asking you to do:
(The intention of the question is to demonstrate that all super class constructors are implicitly called (recursively) when an instance of a subclass is created.)
public class Hop {
public Hop() {
System.out.println("Hop");
}
public static void main(String args[]) {
Jump j = new Jump();
}
}
class Skip extends Hop {
public Skip() {
System.out.println("Skip ");
}
}
class Jump extends Skip {
public Jump() {
System.out.println("Jump ");
}
}
Read the question carefully. Follow the instructions. Try to think what the question is meant to demonstrate.
Related
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.
there I'm pretty new to Java and have german class and method titles. This Code is meant to give a string output for every class extending "Musiker". I have already looked on SO but my problem is that changing it to static gives an error on the class itself. The main reason why I open a new Question is, that every other class is working as planned. And please don't wonder why the Strings look weird, the Book I copied this from is meant to be humoristic.
public class Proberaum {
public static void main(String[] args) {
try {
Musiker saenger = new Saenger();
Musiker gitarrist = new Gitarrist();
Musiker bassist = new Bassist();
Musiker trompeter = new Trompeter();
Musiker backgroundSaengerin = new BackgroundSaengerin();
machtMusik(saenger, gitarrist, bassist, trompeter, backgroundSaengerin);
} catch(Exception e) {
new Exception().printStackTrace();
}
}
public static void machtMusik(Musiker... gruppe) {
for(Musiker musiker : gruppe) {
musiker.musizieren();
}
}
public class Musiker {
private String name;
private int alter;
private Band band;
public void musizieren() {
System.out.println("OO Mmmmmmmmh, OO Mmmmmmmmh");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAlter() {
return alter;
}
public void setAlter(int alter) {
this.alter = alter;
}
public Band getBand() {
return band;
}
public void setBand(Band band) {
this.band = band;
}
}
public class Band {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Saenger extends Musiker {
#Override
public void musizieren() {
this.singen();
}
public void singen() {
System.out.println("Oh, bäbi, juuuu a mei sannnnscheiiiiin");
}
}
public class BackgroundSaengerin extends Saenger {
}
public class Bassist extends Musiker {
}
public class Gitarrist extends Musiker {
public void musizieren() {
System.out.println("Tschiiiiiingzäääängggggg");
}
}
public class Trompeter extends Musiker {
}
}
Your Saenger class is actually a non-static member of the Proberaum class. Because it's non-static, you actually need to create an instance of Proberaum before you can use any of these classes:
Proberaum proberaumObject = new Proberaum();
Musiker saenger = new proberaumObject.Saenger();
In your case, classes inside classes is probably not what you want to do. If you extract each of your classes into its own file, you should find your problem going away. (If that's not possible for whatever reason, declaring your subclasses as static should work too.)
Like Joe C also mentioned in his answer: the core of the problem is that your classes Saenger, Musiker, etc etc. are all nested classes (nested inside Proberaum), but they are defined as non-static.
In Java, non-static nested classes are called "inner classes". Inner classes have implicit access to their enclosing class members (even private ones), but of course the flipside of this is that there first needs to be an object of that enclosing class for the inner class to reference. That is why the compiler is complaining in your example: you're trying to create an object of class Saenger, which is an inner class of Proberaum, so to create that object it needs to have a reference to an object of type Proberaum. Since you're doing the object creation in the (static) main method, no such object exists.
So, to fix, you have to change your inner classes. Easiest is to declare them all static. Note that you can do this is in addition to be making them public:
public static class Seanger extends Musiker { ...
As also remarked elsewhere however, you really should not put every class in the same file. Learn to work with one class per file, it's the Java Way™.
Instead of declaring the nested classes as static, one can alternatively create objects of nested classes like mentioned below.
Proberaum proberaumObject = new Proberaum();
Musiker saenger = proberaumObject.new Saenger();
Let's say we have a class with the following method:
public class Entry {
private String name;
public static Entry getOrCreate(String name) {
// ...
return new Entry(name);
}
}
This class may be subclassed (e.g. SubEntry), and the logic behind "getOrCreate" does not change. But the subclasses should not return a new object of the type Entry, but of the type of the respective subclass (e.g. return SubEntry(name))
How can I realize this without reimplementing the method getOrCreate for every subclass of Entry? Is there a term for this kind of technique?
Subclassing Entry does not affect the getOrCreate method because static methods are not part of a class instance; they do not logically belong in any class.
If you instead move getOrCreate into a non-static Factory class, you can use some Generics magic to determine the returned type:
public class Entry {
private String name;
}
abstract class AbstractEntryFactory<T extends Entry>
public abstract T getOrCreate(String name);
}
public class EntryFactory extends AbstractEntryFactory<Entry>
#Override
public Entry getOrCreate(String name) {
// ...
return new Entry(name);
}
}
public class SubEntryFactory extends AbstractEntryFactory<SubEntry>
#Override
public SubEntry getOrCreate(String name) {
// ...
return new SubEntry(name);
}
}
Actually calling the getOrCreate would look different from what it would look like with your code. Instead of this:
Entry myEntry = Entry.getOrCreate("my name");
It would instead look like this:
Entry myEntry = new EntryFactory().getOrCreate("my name");
Or this:
SubEntry myEntry = new SubEntryFactory().getOrCreate("my name");
Assuming you wanted to be able to call Entry.getOrCreate() to create a type of SubEntry, you'll have to pass along some extra information. The reason is that the getOrCreate() method is not inherited by SubEntry, since it is a static method. So if you want to call it the way I mentioned, you'll have to pass along the class name that you want to create. In the code below there are no checks to validate that Class clazz is an Entry or a subtype, but this gives you a start.
import java.lang.reflect.Constructor;
public class TestClass {
public static void main(String[] args) {
Entry entry = (Entry)Entry.getOrCreate("entry", Entry.class);
SubEntry subEntry = (SubEntry)SubEntry.getOrCreate("subEntry", SubEntry.class);
System.out.println("entry class: " + entry.getClass().getName());
System.out.println("subEntry class: " + subEntry.getClass().getName());
}
}
class Entry {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static Object getOrCreate(String name, Class clazz) {
// If a constructor is created that takes a String, such as "public Entry(String name)",
// then each sub class will need to implement that method. Instead I used a getter and
// setter for the name attribute.
try {
Entry entry = (Entry)clazz.newInstance();
entry.setName(name);
return entry;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
class SubEntry extends Entry {
}
The end result is this output:
entry class: Entry
subEntry class: SubEntry
There are two questions you are asking:
How do I do this?
What is this technique called?
The second one is much more important than the first.
It seems to me like what you are trying to achieve is similar to the concept of cloning (link) or virtual constructor. But you would like this to be a static method, which raises the question as to why? Since a static method is tied to a certain class, not an instance, you should call it through that class in which case you may just as well explicitly be calling new. But having searched for "retrive class in static context" I would say it is not possible to do exactly what you wrote in the question.
If you convert the static method to a normal method, this can be done by using reflection:
class Entry {
private String name;
public Entry(String name) {
this.name = name;
}
public Entry() {
this.name = null;
}
public Entry getOrCreate(String name) {
try {
return getClass().getConstructor(String.class).newInstance(name);
} catch (Exception e) {
return new Entry(name);
}
}
}
class BetterEntry extends Entry {
public BetterEntry(String name) {
super(name);
}
public BetterEntry() {
super();
}
}
You would then be calling the function from an instance, like so:
Entry a = new Entry().getOrCreate("First");
Entry b = new BetterEntry().getOrCreate("Second");
Entry c = b.getOrCreate("Third");
The dynamic types of a, b, c are Entry, BetterEntry and BetterEntry. You could leave out the default constructors, but I added them to make calling getOrCreate feel more like a static method.
If you really want the method to be static, the simplest way would be to just reimplement this function in every subclass.
This is my code and i am trying to pass the parameter from main to cat class but its saying no constructor cant figure out what to do a little help would be appreciated.
public class Cat extends Animal implements Pet {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat(String name, int legs) {
super(4);
this.name = name;
}
public Cat() {
this("Fluppy"); //ERROR OVER HERE
}
#Override
public void play() { //THIS METHOD IS OVERRIDDEN FROM PET INTERFACE
System.out.println(name+"Likes to play with string");
}
#Override
public void eat() { /*THIS METHOD IS OVERRIDDEN FROM ANIMAL ABSTRACT METHOD.*/
System.out.println("Cats likes to eat spiders and fish");
}
}
and the main class
public class PetMain {
public static void main(String[] args) {
Animal a;
Pet p;
Cat c= new Cat("Tom"); //IM GETTING THE ERROR OVER HERE.
c.eat();
c.walk();
c.play();
}
}
try using the correct constructor which takes two parameters
Cat c= new Cat("Tom", 4);
and
this("Fluppy", 4);
or make a new constructor for one parameter like
public Cat(String name) {
this (name, 4);
}
Take a look at your constructors in Cat
public Cat(String name, int legs) { // accept String and int constructor
super(4);
this.name = name;
}
public Cat() { // no argument constructor
this("Fluppy");
}
There is no matching for new Cat("String")
You can add new constructor
public Cat(String anyThing) {
}
First thing when you call this
Cat c= new Cat("Tom");
It expects that you Cat class have a single argument constructor which your class doesnot contain so create a single argument constructor in your Cat class like this
public Cat(String str) {
// your logic
}
Secondly this("Fluppy"); //ERROR OVER HERE
If you know about constructor chaining then you would not have done this. this() is usually used when you want to call another constructor of the same class from within one constructor in your case you are calling one-parameterized constructor from you default constructor since one-parameterized constructor doesnot exist it is giving you compilation error
You are trying to overload the constructor at:
public Cat() {
this("Fluppy"); //ERROR OVER HERE
}
but the call made is for the constructor with one String argument. You do not have a constructor with one String argument , So you have an error try to add.
public Cat(String catty) {
// initialise
}
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
}
public void doIt()
{
new Son().printMe();
}
The function doIt will print "dad". Is there a way to make it print "son"?
In short, no, there is no way to override a class variable.
You do not override class variables in Java you hide them. Overriding is for instance methods. Hiding is different from overriding.
In the example you've given, by declaring the class variable with the name 'me' in class Son you hide the class variable it would have inherited from its superclass Dad with the same name 'me'. Hiding a variable in this way does not affect the value of the class variable 'me' in the superclass Dad.
For the second part of your question, of how to make it print "son", I'd set the value via the constructor. Although the code below departs from your original question quite a lot, I would write it something like this;
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void printName() {
System.out.println(name);
}
}
The JLS gives a lot more detail on hiding in section 8.3 - Field Declarations
Yes. But as the variable is concerned it is overwrite (Giving new value to variable. Giving new definition to the function is Override). Just don't declare the variable but initialize (change) in the constructor or static block.
The value will get reflected when using in the blocks of parent class
if the variable is static then change the value during initialization itself with static block,
class Son extends Dad {
static {
me = "son";
}
}
or else change in constructor.
You can also change the value later in any blocks. It will get reflected in super class
Yes, just override the printMe() method:
class Son extends Dad {
public static final String me = "son";
#Override
public void printMe() {
System.out.println(me);
}
}
You can create a getter and then override that getter. It's particularly useful if the variable you are overriding is a sub-class of itself. Imagine your super class has an Object member but in your sub-class this is now more defined to be an Integer.
class Dad
{
private static final String me = "dad";
protected String getMe() {
return me;
}
public void printMe()
{
System.out.println(getMe());
}
}
class Son extends Dad
{
private static final String me = "son";
#Override
protected String getMe() {
return me;
}
}
public void doIt()
{
new Son().printMe(); //Prints "son"
}
If you are going to override it I don't see a valid reason to keep this static. I would suggest the use of abstraction (see example code). :
public interface Person {
public abstract String getName();
//this will be different for each person, so no need to make it concrete
public abstract void setName(String name);
}
Now we can add the Dad:
public class Dad implements Person {
private String name;
public Dad(String name) {
setName(name);
}
#Override
public final String getName() {
return name;
}
#Override
public final void setName(String name) {
this.name = name;
}
}
the son:
public class Son implements Person {
private String name;
public Son(String name) {
setName(name);
}
#Override
public final String getName() {
return name;
}
#Override
public final void setName(String name) {
this.name = name;
}
}
and Dad met a nice lady:
public class StepMom implements Person {
private String name;
public StepMom(String name) {
setName(name);
}
#Override
public final String getName() {
return name;
}
#Override
public final void setName(String name) {
this.name = name;
}
}
Looks like we have a family, lets tell the world their names:
public class ConsoleGUI {
public static void main(String[] args) {
List<Person> family = new ArrayList<Person>();
family.add(new Son("Tommy"));
family.add(new StepMom("Nancy"));
family.add(new Dad("Dad"));
for (Person person : family) {
//using the getName vs printName lets the caller, in this case the
//ConsoleGUI determine versus being forced to output through the console.
System.out.print(person.getName() + " ");
System.err.print(person.getName() + " ");
JOptionPane.showMessageDialog(null, person.getName());
}
}
}
System.out Output : Tommy Nancy Dad
System.err is the same as above(just has red font)
JOption Output: Tommy then Nancy then Dad
This looks like a design flaw.
Remove the static keyword and set the variable for example in the constructor. This way Son just sets the variable to a different value in his constructor.
Though it is true that class variables may only be hidden in subclasses, and not overridden, it is still possible to do what you want without overriding printMe () in subclasses, and reflection is your friend. In the code below I omit exception handling for clarity. Please note that declaring me as protected does not seem to have much sense in this context, as it is going to be hidden in subclasses...
class Dad
{
static String me = "dad";
public void printMe ()
{
java.lang.reflect.Field field = this.getClass ().getDeclaredField ("me");
System.out.println (field.get (null));
}
}
https://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html
It's called Hiding Fields
From the link above
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super, which is covered in the next section. Generally speaking, we don't recommend hiding fields as it makes code difficult to read.
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String _me = me = "son";
}
public void doIt()
{
new Son().printMe();
}
... will print "son".
It indeed prints 'dad', since the field is not overridden but hidden. There are three approaches to make it print 'son':
Approach 1: override printMe
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
#override
public void printMe()
{
System.out.println(me);
}
}
public void doIt()
{
new Son().printMe();
}
Approach 2: don't hide the field and initialize it in the constructor
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
public Son()
{
me = "son";
}
}
public void doIt()
{
new Son().printMe();
}
Approach 3: use the static value to initialize a field in the constructor
class Dad
{
private static String meInit = "Dad";
protected String me;
public Dad()
{
me = meInit;
}
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
private static String meInit = "son";
public Son()
{
me = meInit;
}
}
public void doIt()
{
new Son().printMe();
}
Variables don't take part in overrinding. Only methods do. A method call is resolved at runtime, that is, the decision to call a method is taken at runtime, but the variables are decided at compile time only. Hence that variable is called whose reference is used for calling and not of the runtime object.
Take a look at following snippet:
package com.demo;
class Bike {
int max_speed = 90;
public void disp_speed() {
System.out.println("Inside bike");
}
}
public class Honda_bikes extends Bike {
int max_speed = 150;
public void disp_speed() {
System.out.println("Inside Honda");
}
public static void main(String[] args) {
Honda_bikes obj1 = new Honda_bikes();
Bike obj2 = new Honda_bikes();
Bike obj3 = new Bike();
obj1.disp_speed();
obj2.disp_speed();
obj3.disp_speed();
System.out.println("Max_Speed = " + obj1.max_speed);
System.out.println("Max_Speed = " + obj2.max_speed);
System.out.println("Max_Speed = " + obj3.max_speed);
}
}
When you run the code, console will show:
Inside Honda
Inside Honda
Inside bike
Max_Speed = 150
Max_Speed = 90
Max_Speed = 90
only by overriding printMe():
class Son extends Dad
{
public void printMe()
{
System.out.println("son");
}
}
the reference to me in the Dad.printMe method implicitly points to the static field Dad.me, so one way or another you're changing what printMe does in Son...
You cannot override variables in a class. You can override only methods. You should keep the variables private otherwise you can get a lot of problems.
No. Class variables(Also applicable to instance variables) don't exhibit overriding feature in Java as class variables are invoked on the basis of the type of calling object. Added one more class(Human) in the hierarchy to make it more clear. So now we have
Son extends Dad extends Human
In the below code, we try to iterate over an array of Human, Dad and Son objects, but it prints Human Class’s values in all cases as the type of calling object was Human.
class Human
{
static String me = "human";
public void printMe()
{
System.out.println(me);
}
}
class Dad extends Human
{
static String me = "dad";
}
class Son extends Dad
{
static String me = "son";
}
public class ClassVariables {
public static void main(String[] abc) {
Human[] humans = new Human[3];
humans[0] = new Human();
humans[1] = new Dad();
humans[2] = new Son();
for(Human human: humans) {
System.out.println(human.me); // prints human for all objects
}
}
}
Will print
human
human
human
So no overriding of Class variables.
If we want to access the class variable of actual object from a reference variable of its parent class, we need to explicitly tell this to compiler by casting parent reference (Human object) to its type.
System.out.println(((Dad)humans[1]).me); // prints dad
System.out.println(((Son)humans[2]).me); // prints son
Will print
dad
son
On how part of this question:- As already suggested override the printMe() method in Son class, then on calling
Son().printMe();
Dad's Class variable "me" will be hidden because the nearest declaration(from Son class printme() method) of the "me"(in Son class) will get the precedence.
Just Call super.variable in sub class constructor
public abstract class Beverage {
int cost;
int getCost() {
return cost;
}
}`
public class Coffee extends Beverage {
int cost = 10;
Coffee(){
super.cost = cost;
}
}`
public class Driver {
public static void main(String[] args) {
Beverage coffee = new Coffee();
System.out.println(coffee.getCost());
}
}
Output is 10.
Of course using private attributes, and getters and setters would be the recommended thing to do, but I tested the following, and it works... See the comment in the code
class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
/*
Adding Method printMe() to this class, outputs son
even though Attribute me from class Dad can apparently not be overridden
*/
public void printMe()
{
System.out.println(me);
}
}
class Tester
{
public static void main(String[] arg)
{
new Son().printMe();
}
}
Sooo ... did I just redefine the rules of inheritance or did I put Oracle into a tricky situation ?
To me, protected static String me is clearly overridden, as you can see when you execute this program. Also, it does not make any sense to me why attributes should not be overridable.
Why would you want to override variables when you could easily reassign them in the subClasses.
I follow this pattern to work around the language design. Assume a case where you have a weighty service class in your framework which needs be used in different flavours in multiple derived applications.In that case , the best way to configure the super class logic is by reassigning its 'defining' variables.
public interface ExtensibleService{
void init();
}
public class WeightyLogicService implements ExtensibleService{
private String directoryPath="c:\hello";
public void doLogic(){
//never forget to call init() before invocation or build safeguards
init();
//some logic goes here
}
public void init(){}
}
public class WeightyLogicService_myAdaptation extends WeightyLogicService {
#Override
public void init(){
directoryPath="c:\my_hello";
}
}