I know that interfaces in Java are handled by the virtual machine as abstract classes. So, every class in Java, abstract or not has a constructor. Does this mean that interfaces have a constructor too? Because too me on one hand makes sense to have a constructor since they are abstract classes. On the other hand it doesn´t make sense since interfaces don´t have any attributes to initialize.
So how does it actually work?
Interfaces don't have constructors. Their implementations do.
All an interface is:
interface MyInterface{
void addNumber(int amount);
void subtractNumber(int amount);
int getNumber();
}
You don't "run" an interface, and an interface isn't something you create objects out of.
The class that implements your interface does have a constructor though:
class MyNumber implements MyInterface{
private int myNumber;
//Here is your constructor, called when you instantiate it.
myNumber(int number){
myNumber = number;
}
//Now you need to add the methods in your interface
public void addNumber(int number){
myNumber = myNumber + number;
}
public void subractNumber(int number){
myNumber = myNumber - number;
}
public int getNumber(){
return myNumber;
}
}
So no, interfaces do not have constructors. Hope this helps!
Edit: When you create your object, you call your constructor:
MyNumber number = new MyNumber(5); //Calls the constructor and creates a new MyNumber with the value of 5.
number.addNumber(6); //Adds 6 to your number, it is now 11.
number.subtractNumber(3); //Subracts 3 from your number, it is now 8.
number.getNumber(); //returns the value of myNumber inside of your MyNumber object, which is 8.
Edit 2: I want to elaborate a little more on interfaces. You are correct in saying they don't have any attributes to initilize. They have methods to IMPLEMENT. If you have a "move" method in your interface, it can apply to many, many different things. Cars, dogs, boats, planes, sloths and snakes all move, but how do they move? Cars move faster than sloths, so it moves differently. When you create classes for whatever you need to move, you can change that move method and tailor it to the situation you need. That's the point of an interface, flexibility.
Related
If I have three classes as follows:
package com.Bob.Marley;
public class SuperClass{
protected int x = 0;
}
package com.Bob.Marley;
public class SubClass extends SuperClass{
protected int x = 1;
}
package com.Bob.Marley;
public class TestClass{
public static void main (String[] args){
SubClass s = new SubClass();
//print 1
System.out.println(s.x);
//how do I print the superclass variable?
//I know inside SubClass I can access it with plain old super.x
//but what about outside the subclass with a new object.
}
}
So the question is how would I print out 0 from the superclass of the new object s created in a separate class. System.out.println(s.super.x); does not work. I don't think it changes anything but I am using java 8.
The expression s.super.x is invalid here. Whenever you prefix a super.x with something, it should be a type name, not a variable name, e.g. SuperClass.super.x. However, this would be valid only inside the subclass for accessing the superclass of the enclosing class, which does not exist here.
Cast x to be a SuperClass so you can access the x declared in Superclass.
System.out.println( ((SuperClass) s).x);
or
SuperClass sc = (SuperClass) s;
System.out.println(sc.x);
This works because variable access is statically binded. The type of the variable or expression determines the scope searched for variable access.
TL;DR: if you introduce a new field in a subclass, don't re-use a field name from the parent class. You gain nothing, only confusion and problems.
If I understand correctly, you want SubClass instances to have two fields, one inherited from the SuperClass (for the discussion, let's rename that to superX to make things clearer), and one from the subclass itself (let's rename that to subX).
For a given SubClass instance, you want to be able to access both fields, superX and subX (of course, using different expressions). What makes things difficult in your code sample, is the fact that you chose to give both of them the same name x.
So, if you really want your instances to carry both fields, I'd recommend to rename them, so you don't have to use ugly tricks like casting to the SuperClass.
public class SuperClass{
protected int superX = 0;
}
public class SubClass extends SuperClass{
protected int subX = 1;
}
But, if x stands for the same property with the same meaning for both the super and the sub class, just with different initial values, then it doesn't make sense to have two different fields, and you should change the code to become:
public class SuperClass{
protected int x = 0;
}
public class SubClass extends SuperClass{
// constructor initializes the x field with 1.
public SubClass(){
x = 1;
}
}
Of course, then it's impossible to get two different values from a single instance of SubClass.
I want to create data structures to capture the following ideas:
In a game, I want to have a generic Skill class that captures general information like skill id, cool down time, mana cost, etc.
Then I want to have specific skills that define actual interaction and behaviours. So these would all extend from base class Skill.
Finally, each player will have instances of these specific skills, so I can check each player's skill status, whether a player used it recently, etc.
So I have an abstract superclass Skill that defines some static variables, which all skills have in common, and then for each individual skill that extends Skill, I use a static block to reassign the static variables. So I have the following pattern:
class A {
static int x = 0;
}
class B extends A {
static {
x = 1;
}
}
...
// in a method
A b = new B();
System.out.println(b.x);
The above prints 1, which is exactly the behaviour I want. My only problem is that the system complains about I'm accessing static variable in a non-static way. But of course I can't access it in that way, because I only want to treat the skill as Skill without knowing exactly which subclass it is. So I have to suppress the warning every time I do this, which leads me to think whether there is a better/neater design pattern here.
I have thought about making the variables in question non-static, but because they should be static across all instances of the specific skill, I feel like it should be a static variable...
You should generally avoid such use of global state. If you know for sure that the field x will be shared across all instances of all subtypes of the base class, then the correct place to put such a field is probably somewhere other than the base class. It may be in some other configuration object.
But even with your current configuration, it just does't make sense since any subclass that modifies the static variable will make the variable visible to all classes. If subclass B changes x to 1, then subclass C changes it to 2, the new value would be visible to B as well.
I think that the way you described in the question, every subclass should have its own separate static field. And in the abstract base class, you can define a method to be implemented by each subclass in order to access each field:
abstract class A {
public abstract int getX();
}
class B extends A {
public static int x = 1;
public int getX() {
return x;
}
}
class C extends A {
public static int x = 2;
public int getX() {
return x;
}
}
As already pointed out by some answers and comments, your approach won't work the way you want because every static block changes the static variable for all classes extending A.
Use an interface and instance methods instead:
public interface A {
int getX();
}
-
public class B implements A {
private static final int X = 1;
#Override
public int getX() {
return X;
}
}
-
A myInstance = new B();
System.out.println(myInstance.getX()); // prints "1"
I've recently started taking an intro java class(I apologize in advance for my lack of knowledge) and I've run into some trouble. I was required to make a program that contains 3 data fields, 2 constructors, and 4 methods.
I'm having a hell of a time trying to put some input into this, where the user would choose from 1 of the 3 data fields I made up for car prices and choose their vehicle. As far as the constructors go, I made a default one but I'm not sure on how to A) implement another constructor and B) how do I involve the input into this and C) where the methods go in that.
I'm thinking of putting the input first but that ruins my constructors?
I realize I asked a lot, but this is an online class without a text, and I'm basically starving for knowledge. I've included what I got so far below. Feedback is appreciated. Again, I apologize for the lack of knowledge but I'm trying --
public class Vehicle{
int truck;
int car;
int van;
public Vehicle(int t, int c, int v){
truck=t;
car=c;
van=v;
}
public Vehicle(){
truck=0;
car=0;
van=0;
}
}
public static void main (String[] args) {
Vehicle cost= new vehicle(25000,15000,22500);
//*cost.truck=25000; cost.car=15000; cost.van=22500;*//
Vehicle this Vehicle= new vehicle();
Vehicle choice Vehicle= new vehicle(25000,22500);
system.out.println("Default prices are 25000 for a truck, 15000 for a car, and"
+ "22500 for a van, you chose" +
}
}
Based from your question, you must be asking all about how to define classes and use them in general.
Question A. How to implement another constructor?
From your case, I see that you've already define your own constructor, but having problem to define another. To define another constructor, you have to know your parameters that
would be passed.
Here, you have three arguments. (variable t, c, v).
public Vehicle(int t, int c, int v){
truck=t;
car=c;
van=v;
}
Another, constructor with no arguments.
public Vehicle(){
truck=0;
car=0;
van=0;
}
When you define another constructor, you must not define another three arguments constructor of the same type, or another constructor with no arguments.
Therefore, you can have constructor method like this.
public Vehicle(int veh, int price){
switch (veh) {
case 0:
truck = price;
case ...
}
}
Question B. How do I involve the input? Where to involve them in methods
From your problem, this statement is already calling constructor, Which means, you are already involving an input to a class.
Vehicle cost = new Vehicle(25000,15000,22500);
Which is the same as calling a constructor with no arguments, and setting the current prices for the vehicles.
Vehicle choice = new Vehicle();
choice.truck = 25000;
choice.car = 22500;
Now, if you are thinking of is there another way to input datas through methods. It is called Encapsulation. To achieve this OOP concept, you should define data members as Private.
private int truck;
// public int truck; <- not like this.
Then, you can have involve input and probably output. Using the concept of getters and setters. In which you involve methods.
// simple setter
public void setTruckPrice(int t) {
truck = t;
}
// simple getter
public int getTruckPrice(int t) {
return truck;
}
P.S. i forgot to edit its encapsulation.
If you want more information, just refer to these links.
http://docs.oracle.com/javase/tutorial/java/javaOO/classes.html
http://www.tutorialspoint.com/java/index.htm
This question already has answers here:
Managing constructors with many parameters in Java
(8 answers)
Closed 6 years ago.
Assume that I have some subclasses that extend a superclass. These subclasses differ by the parameters passed to the superclass. Unfortunately, like the following example, I can end up with "many" parameters. Is there a general method of avoiding this? Are constructors with "many" arguments considered good practice? Would it be better to have getter/setter methods instead of passing every parameter via constructor?
public abstract class SuperClass {
private int a;
private int b;
.
.
private int z;
public SuperClass(int a, int b, ... int z) {
this.a = a;
this.b = b;
.
.
this.z = z;
}
}
public class SubClass1 extends SuperClass {
public SubClass1() {
super(4, 3, ..., 9);
}
}
public class SubClass2 extends SuperClass {
public SubClass2() {
super(1, 7, ..., 2);
}
}
If your subclasses vary only in the parameters passed to the superclass, you might be looking for the Builder Pattern. A builder for the superclass lets you pass in whatever parameters you need without cluttering your constructor, and if you want subclasses for readability, you can just wrap a call to the builder and return its result from the subclass constructors.
Generally, constructors with many parameters is a code smell. It means you probably have a class that breaks the "Single Responsibility Principle". If you can't avoid it, try using the builder pattern!
I would not have constructors in my classes as the behavior of the objects instantiated by each constructor may be different and hard to determine.
One thing to check is: should SuperClass be split into simpler classes?
If this can't be done: if you have too many parameters then you can have a special class that holds the parameters; with setters and getters for each parameter.
One can fill the values in from property files, so you can have profiles for common cases.
class SuperClassParam
{
void seta(int a);
int geta();
//...
}
class SuperClass
{
public SuperClass( SuperClassParam params )
{
}
If the number of parameters can vary, then use a variable arity ("varargs") parameter. Declare an array instead of all those other instance variables. The variable arity parameter is typed as an array when in the method.
private int[] all;
public SuperClass(int... all) {
this.all = all;
}
Your subclass constructors will not have to change at all.
What's the difference between calling a method through an object vs a class.
for example the Class Bob
public class SecretNumber() {
public static int secretNumber = 2;
public static void changeSecretNumber(){
secretNumber++;
}
}
What would be the difference if i called it like an object
SecretNumber secretNumber = new SecretNumber();
secretNumber.changeSecretNumber();
vs calling it like this
SecretNumber.changeSecretNumber();
How would one method effect the other?
The result is the same.
You should call it by class name, not through the instance, because no dynamic dispatch happens.
Most compilers will give you a warning, if you do that, too. Some people argue that it should have been made a compile error.
In Java, unless a class method is "static", you can't call it except through an object instance.
Here's an example of a method where it would make sense to declare it "static":
http://www.leepoint.net/notes-java/flow/methods/50static-methods.html
public static double mean(int[] p) {
int sum = 0; // sum of all the elements
for (int i=0; i
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
The second form isn't valid Java. You can only call methods on a class if they are declared static.
Calling a method through a class is a static method. Unless you declare the method a static method, the compiler will give you a compile error .