I am trying to learn java. Forgive me if my concepts are not clear or very wrong.
I am trying to create inheritance and polymorphism application.
I have created an array of Animals[5]. I am trying to add refrences of dog, cat to the array.
I want it to hold
Animals[0] = zooDog
I am getting error that
cannot make a static reference to the non-static
I have create AnimalstestDrivve class
package animals;
public class AnimalstestDrive {
public Animals[] myZoo = new Animals[5];
int zooCounter = 0;
public static void main(String[] args) {
//Set animals array
Dog zooDog = new Dog();
addAnimals(zooDog);
Cat zooCat = new Cat();
addAnimals(zooCat);
}
public void addAnimals(Animals a){
if ( zooCounter > 5 ){
myZoo[zooCounter] = a;
zooCounter++;
}
else
System.out.println("Zoo is full");
}
}
here is my Animals class
package animals;
public abstract class Animals {
private String Name;
private int Size; //Size on the scale 1 to 10
public void eatFood(){
System.out.println("I am eating food");
}
public void sleep(){
System.out.println("I am sleeping now");
}
abstract public void makeNoises();
}
Simple dog, cat class
package animals;
public class Dog extends Animals {
public void makeNoises(){
System.out.println("Bow! bow!");
}
}
The main method (static) attempts to call the addAnimals method, whose declaration is non-static. You need to create an instance of the class first, then call the method on this instance
AnimalstestDrive testDrive = new AnimalstestDrive();
Dog zooDog = new Dog();
testDrive.addAnimals(zooDog);
See Understanding Class Members for more information
You need to have an instance of the class AnimalstestDrive. Static means, that you don't need any instance of the class to use the class method, so if you would mark the addAnimals as static, You could use that method without creating an instance of AnimalstestDrive.
Because the method addAnimals is not static, you need to create an instance of AnimalstestDrive to use that function.
When a method is not static, it is specific to an instance of that class. For example:
AnimalstestDrive atd = new AnimalstestDrive();
atd.addAnimals(new Dog()); // this will add animals to "atd"
If a method is static, it is not specific to an instance of the class, but the class itself.
If you put this method in the class AnimalstestDrive:
public static void staticMethod() {
}
You could only access it with AnimalstestDrive.staticMethod(), not atd.staticMethod().
More info on static methods here.
Related
This question already has answers here:
Calling newly defined method from anonymous class
(6 answers)
Closed 1 year ago.
I just came to know that there is a process called in-line class with the help of which I can create a new object and modify its class methods on the fly. I don't know if I can create new methods and variables inside the in-line class and use them. So I did this experiment. My IDE did not show any error while creating a new method inside the in-line class. Now I don't know how to access the newly created method. My doubt is, can I create a new method while creating an in-line class?(If yes then how?) Or, in-line class is only for overloading the existing methods?
public class Main {
public static void main(String[] args) {
Animals cat = new Animals("Cat") {
#Override
public void makeNoise() {
System.out.println("MEOW MEOW");
}
public void color() {
System.out.println("Color is: white");
}
};
cat.makeNoise();
cat.color(); //this is showing error
}
}
Animal class
class Animals {
private String name;
public Animals(String name) {
this.name = name;
}
public void makeNoise() {
System.out.println("Sound of the animal");
}
}
The easiest change: use var:
public static void main(String[] args) {
var cat = new Animals("Cat") {
#Override
public void makeNoise() {
System.out.println("MEOW MEOW");
}
public void color() {
System.out.println("Color is: white");
}
};
cat.makeNoise();
cat.color();
}
This now works, because cat isn't an Animals, it's inferred as a more specific type than that - it's a class that doesn't have an accessible name, so you can't write it as an explicit variable.
In fact, you were able to access anonymous class methods prior to the introduction of var, in a way:
new Animals("Cat") {
// ...
public void color() { ... }
}.color();
This worked prior to var, because the expression new Animals("Cat") { ... } has a more specific type that Animals. The problem is, you can only invoke those extra methods directly on the new instance creation expression, because you can only assign it to a variable of type Animals (or a superclass), thus preventing the compiler from accessing the specific class methods.
An alternative would be to declare it as a named class.
The most similar to what you have here would be a local class, although they are pretty rarely used (if known about at all), in my experience:
public static void main(String[] args) {
class Cat extends Animals {
Cat() { super("Cat"); }
// ...
public void color() { ... }
}
Cat cat = new Cat();
cat.color();
}
This is sort-of what the var approach does; it just gives the type an explicit name. This approach would be good if you wanted to create more than one instance of Cat in that method.
But there's not an obvious reason why this would need to be a local class: you could alternatively declare it as a nested or inner class, or, of course, a top-level class.
You cannot do that.. The first thing is Animals class has no method name Color.
I'm not sure how exactly to phrase my question.
So, I have an interface reference and I'm creating a new object. The new object obviously implements said interface. The initial class inherits another class. That sub-class inherits the super class. However, I cannot access data from super class from the main method without casting the reference first. I'll show an example below
public class a {
public int getSomeData1() {
return someData;
}
}
public class b extends a implements someInterface {
// Some behavior.
}
public class c extends b implements someInterface {
// Some behavior.
}
public class Main {
public static void main(String[] args) {
someInterface obj = new b();
obj.someData1(); // I cannot access someData1().
c anotherObj = new c();
c.getSomeData1(); // This works however.
}
}
How can I have obj.someData1() actually get the data from class a rather than casting it to a.
Just remember the rule that method invocations allowed by the compiler are based solely on the declared type of the reference, regardless of the object type.
If it is not very clear, here is another version of this rule: what is on the left side defines methods you can call, no matter what is on the right :)
Here are a few examples to make it more clear:
public interface Animal {
void voice();
}
public class Dog implements Animal {
public void voice() {
System.out.println("bark bark");
}
public void run() {
// impl
}
}
When you create a dog like this:
Animal dog1 = new Dog();
The reference type which is Animal defines which methods are allowed for you to call. So basically you can only call:
dog1.voice();
When you create a dog like this:
Dog dog2 = new Dog();
The reference type which is Dog, so you are allowed to call:
dog2.voice();
dog2.run();
This rule remains also when you have class inheritance, not only when you implement an interface. Let's say we have something like:
public class SpecialDog extends Dog {
public void superPower() {}
}
And those are examples of what you can call:
Animal dog1 = new SpecialDog();
dog1.voice(); // only this
Dog dog2 = new SpecialDog();
// here you can call everything that Dog contains
dog2.voice();
dog2.run();
SpecialDog dog3 = new SpecialDog();
// here you can call all 3 methods
// this is the SpecialDog method
dog3.superPower();
// those 2 are inherited from Dog, so SpecialDog also has them
dog3.voice();
dog3.run();
In other cases, you need to upcast/downcast to be able to call some specific method.
Happy Hacking :)
Why the reference type object o is not able to access variable a. It is showing error a can't be resolved or is not a field.
public class test2 {
int a;
public static void main(String args[]) {
Object o = new test2();
test2 t = new test2();
t.a = 0;
o.a = 10;
}
}
Basically, you are confused between reference type and instance (object) type.
In your program, o is the reference variable with type Object, so o will be able to access only the methods and variables from Object class.
Also, t is the reference variable with type test2, so t can access class members of test2. You can look here for more details.
In short, reference type decides which members of the class you can access.
Also, look at the below popular classes for Inheritance to understand the above concept:
public class Animal {
public String foodtype;
//other members
}
public class Dog extends Animal {
public String name;
//other members
}
public class Test {
public static void main(String[] args) {
Animal a = new Dog();//'a' can access Anmial class members only
a.foodtype = "meat"; //ok
a.name = "puppy"; //compiler error
Dog d = new Dog();//'d' can access both Animal and Dog class members
d.foodtype = "meat"; //ok
d.name = "puppy";//ok
}
}
In Java, you can't create fields just by assigning to them. You must declare them in your code also:
public class test2 {
int a;
...
}
Even then, if you declare a variable as an Object, that is really a "test2" instance, you still won't be able to access field 'a' without casting it first.
Object o = new test2();
o.a = 5 // compile error
test2 t = (test2)o;
t.a = 5 // ok. Will compile fine
The Java compiler keeps things fairly simple, meaning that it doesn't work hard to see if "o" is really a test2 or not, it just uses the declared class to determine which fields and methods are accessible.
Firstly, Thanks everybody that read that topic.
How can if statement become true in test class? I couldnt find any solution.I couldnt write any code in these method.I tried to send from Room class numberOfTiger to class Question's method but I didnt achieve that.
That's question about ,How can I change int variable(numberofTiger) to Cat.Tiger variable.After that if statement become true to invoke (getNumberOfTiger) method.
public class Test {
public static void main(String[] args) {
Animal an = new Animal();
Animal.Cat an1 = an.new Cat();
Animal.Cat.Tiger an2 = an1.new Tiger(3, 900, 2);
if (Animal.Question.getnumberOfTiger(an2) == 3) {
System.out.println("True");
}
}
}
public class Animal {
Cat[] c;
// inner class
class Cat {
Tiger[] t;
// inner class
class Tiger {
private int numberOfTiger;
private int averageOfTigerWeigth;
private int youngTiger;
public Tiger(int numberOfTiger, int averageOfTigerWeigth, int youngTiger) {
super();
this.numberOfTiger = numberOfTiger;
this.averageOfTigerWeigth = averageOfTigerWeigth;
this.youngTiger = youngTiger;
}
static class Question {
static int getnumberOfTiger(Cat.Tiger a) {
return 0;
}
}
}
In addition to either making Cat a static class, or using its instance,
you also need a getter for a.numberOfTiger since it is private, in Tiger class:
public getNumberOfTiger() {
return numberOfTiger;
}
Then:
return a.getNumberOfTiger();
In getNumberOfTiger() you need to return the number of tigers associated with that object. You are currently just returning 0, so it will always evaluate to false.
I see the issue. The Tiger class and the Cat class needs to be static. The reason is, a non-static inner class can call on its outer class (e.g. Cat.this.something). A non-static inner type is called like this:
instanceOfOuterClass.innerClass
whereas a static inner type is called like this:
outerClassName.innerClass
The simplest way to call on a non-static inner type is new Outer().new Inner(); The main issue with beginners in Java is that they try to do this:
new (new Outer()).Inner()
But the actual way to call it is
new Outer().new Inner()
Also, your method is always returning 0 for the count of tigers.
If there is an enum,
public enum Animal {
DOG,
CAT;
}
If I'm understanding enums correctly, we can convert them in equivalent class, something like -
public class Animal {
private static final DOG = 1;
private static final CAT = 2;
}
Is this the correct representation, or I'm missing anything here?
Thanks.
Not exactly. Here is how it will look like:
public class Animal extends Enum<Enum<Animal>> {
public static final DOG = new Animal("DOG", 0);
public static final CAT = new Animal("CAT", 1);
private static final Animal[] values = new Animal[] {DOG, CAT};
private Animal(String name, int ordinal) {super(name, ordinal);}
public static Animal valueOf(String name) {return Enum.valueOf(Animal.class, name)}
public Animal[] values() {return values;}
}
Class java.lang.Enum holds ordinal and name and provides methods that can access them.
No, your code shows how things ware organized before enum was added in Java 1.5.
Your enum values needs to be public not private because you want to make them accessible everywhere.
Also they value is instance of your enum class, not integer (you may want to invoke some methods on these instances like TimeUnit.SECONDS.toMinutes(120); where you invoke toMinutes on instance SECONDS)
So your code looks more like
public class Animal extends Enum<Animal>{
public static final Animal DOG = new Animal();
public static final Animal CAT = new Animal();
//rest of code added by compiler, like
// - making constructor private
// - handling `ordinal()`
// - adding `valueOf(String) ` and `values()` methods
}