So I already know it's impossible to have a static method in an abstract class. However, is there a way for an overridden method in its child class to be accessed without instantiating it?
For example, let's say I have two classes, an abstract class element and its child class Hydrogen, as shown below. This assumes that I will have multiple similar classes, such as Helium, Boron, etc. which are all child classes of Element.
public abstract class Element {
public abstract double getMolarMass();
}
public final Hydrogen extends Element {
#Override
public double getMolarMass() {
return 1.008;
}
}
How would I be able to be able to call the getMolarMass method without having to instantiate the Hydrogen object?
It seems to me you want to have access to constants in your subclasses while at the same time allowing for polymorphic behavior involving these values. You can have a constant and also return it from your method:
public final class Hydrogen extends Element {
public static final double MOLAR_MASS = 1.008;
#Override
public double getMolarMass() {
return MOLAR_MASS;
}
}
Then, you can access the constant statically: Hydrogen.MOLAR_MASS.
What you want to achieve is creating an Enum. There's an enum keyword allowing you to directly do what you seemingly want to achieve.
An enum is effectively a final class with several public static final member variables, which hold references to instances of the class.
enum Element
{
Hydrogen(1.0),
Helium(2.0),
...;
private double mass;
private Element(double masss)
{
this.mass = mass;
}
public double getMasss()
{
return mass;
}
}
You can access the fields directly, e.g.:
Element e = Element.Helium;
System.out.println("The mass of " + e + " is " + e.getMass());
if the method is not static then you can not call it statically,
on the other hand overriding static methods makes no sense and is not allowed in java...
Related
I have a base class
public class base
{
//some stuff
}
and several subclasses
public class sub1 extends base
{
static int variable;
}
public class sub2 extends base
{
static int variable;
}
etc
The static int variable exists in every subclass because I store in it information that is characteristic for every subclass. But it would be better if there was a way to move static int variable to base class in the way that it still will be different for every subclass.
In the way that it is now I am repeating myself, when adding some another subclass, it's a bad practice.
So anyone has some idea how to acomplish this? Maybe there's a design pattern that fits to this situation?
You cannot move all the different static variables from derived classes into the base class, because static variables are one-per-class; you want your variables to be one-per-subclass, which is not allowed.
You could work around this issue by defining a registry of subclasses in your base class, and store the int for each subclass there. However, this would add a lot more complexity, and it is not clear how you would differentiate between subclasses in the superclass.
Your current solution appears optimal.
Don't use a static field for this - that's not the way to go, because static fields of a subclass do not "override" those of a super class.
Instead, because the values are constant for a given class, use a final instance field:
public class Base {
protected final int variable;
public Base() {
this(5);
}
protected Base(int v) {
variable = v;
}
}
public class Sub1 extends Base {
private static int v = 7;
public Sub1() {
super(v);
}
}
Now the variable is fixed and accessible to all instances.
You can certainly move variable into the base class, but it cannot be static. Alternatively, you can make static getters which you override in each subclass. Here is an example of both:
public class base {
protected int variable;
protected static int getVariable() {
return -1;
}
}
public class Sub1 extends base {
public Base() {
variable = 0;
}
protected static int getVariable() {
return 0;
}
}
public class Sub2 extends base {
public Sub2() {
variable = 1;
}
protected static int getVariable() {
return 1;
}
}
As a design principle, it is somewhat rare (in my opinion) that you genuinely want static methods. Usually you will have some instance of the class around that you are working with. If you want a whole bunch of objects to share some common behavior which you configure at runtime, you might want to check out the flyweight pattern.
I went searching to learn how to do lambda expressions in Java, but instead a confusion came up for me. So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was. Lot of threads and videos I'm seeing seem to call anonymous inner classes just "anonymous classes." Are they synonymous? My understanding of anonymous inner class is:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
So essentially, instead of having to write a subclass for Square, and then override the calculatePerimeter() method, I can just make a one-time square class, and override the method in their. Is this correct?
So, anonymous inner classes have to do with inheritance. I'm not understanding the use of it though. Perhaps, it's because I've never used them before, or because I don't have much programming experience. Can you can give me examples or explain when it's useful?
UPDATE: When I moved my code for the anonymous inner class to an IDE, I learned that there are errors; So apparently, the "square" doesn't even inherit the fields of the rectangle. Doesn't this make it even more useless?
Would the equivalent be:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
}
public class Square extends Rectangle {
#Override
public void calculatePerimeter() {
perimeter = 4*getLength();
}
public double getLength() {
return length;
}
}
So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
There is no anonymous class there. The class SomeObject has a name ... therefore it is not anonymous. In fact, it is just a normal (non-nested, non-inner, non-anonymous) Java class.
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was.
There is no such thing as a "regular anonymous class". All Java anonymous classes are "inner".
As the JLS says:
"An inner class is a nested class that is not explicitly or implicitly declared static.
Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5)."
So, anonymous inner classes have to do with inheritance.
Anonymous inner classes do involve inheritance, but that's not what makes them "inner". See above.
I meant the "list.add(I meant the "list.add(new SomeObject());". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.);". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.
You are incorrect. An object is not a class1.
The new SomeObject() is creating an object, not a class. But that's just normal. Objects / instances don't have names ... as far as the JLS is concerned.
Now variables and fields have names ... but variables are not objects / instances or classes. They are bindings between a name and a slot that can hold a reference to an object (if that's what the type declaration allows).
1 - except in the case of instances of java.lang.Class ... and even then the object is not actually the class / type from a theoretical standpoint.
Or is it called simply an anonymous object and I had two mixed up?
Nope. Objects don't have names. All Java objects are "anonymous". It is not a useful distinction to make. (And see above where I talk about variables ...)
As for your Rectangle / Square examples, they have nothing to do with anonymous classes, inner classes, nested classes or anything like that. They are just top-level classes, using ordinary Java inheritance. (Not that I'm suggesting there is another "non-ordinary" kind of inheritance ...)
First off - square can access fields in Rectangle. You need to mark them protected not private
public class Rectangle {
protected double length;
protected double width;
protected double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
Here are some good descriptions of Inner Classes, Anonymous and local
http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html.
There are two additional types of inner classes. You can declare an inner class within the body of a method. These classes are known as local classes. You can also declare an inner class within the body of a method without naming the class. These classes are known as anonymous classes.
http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
Local classes are classes that are defined in a block, which is a group of zero or more statements between balanced braces. You typically find local classes defined in the body of a method.
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
http://c2.com/cgi/wiki?AnonymousInnerClass
Anonymous Classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
I think the relevance of Anonymous classes comes when you are designing an API. You could create concrete classes to implement every bit of logic for every interface/abstract class but that would create tons of dependencies and you would still be missing some logic. A great example of anonymous classes is when using predicates for filtering. Like in Google Guava
Lets say I have a List<Integer> and I want to filter the numbers remove the 1s and return a new list
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1) rtn.push(i);
}
return rtn;
}
Now lets say I want to filter out 1 and 2
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1 && i != 2) rtn.push(i);
}
return rtn;
}
Now lets say 3 and 5s ... this logic is exactly the same except for the predicate check. So we will create an interface
interface FilterNumber {
public boolean test(Integer i);
}
class Filter1s implements FilterNumber {
public Filter1s(){};
public boolean test(Integer i) { return i != 1; }
}
public static List<Integer> filter(List<Integer> input, FilterNumber filterNumber) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(filterNumber.test(i)) rtn.push(i);
}
return rtn;
}
filter(list, new Filter1s());
As you can see with combinations this becomes tedious too. It would be easier to just allow the user of the api to define the logic they want to preform and if it is only needed once just use an anonymous class
filter(list, new FilterNumber() {
#Override
public boolean test(Integer i) {
return i != 1 && i != 3 && i != 7;
}
});
And extending to Lambdas, wouldn't it be even easier to take out all the bloat around i != 1
list.stream().filter( i -> i != 1 )
To answer a later comment, "when I write a new subclass, it inherits those private instance variables. In the case of the anonymous inner class, it didn't."
Subclasses never "inherit" private fields of the superclass (using the JLS terminology). However, subclasses may be able to refer to those private fields anyway, depending on where they're located. If the subclass is declared inside the superclass, or if they're both nested inside the same top-level class, the methods of the subclass can still access the field; assuming you have a source file C.java with just one class C, private fields declared somewhere in C.java are still accessible from most other places in C.java.
However, when testing this, I found some interesting nuances:
class Foo1 {
private int bar1;
public static class Foo2 extends Foo1 {
public void p() {
System.out.println(bar1); // illegal
System.out.println(((Foo1)this).bar1); // works
}
}
}
bar1 is visible, even though it's a private field in the superclass; it's not inherited, but you can access it by telling the compiler to look at the Foo2 object as a Foo1. But just referring to bar1 by itself fails; Java interprets this as an attempt to get the bar1 of the enclosing instance (not the superclass), but Foo2 is static, so there is no enclosing instance.
Note that if Foo2 were declared outside Foo1, the second println would be illegal, because now bar1 is not visible at all, since it's private. The moral here is that "inheritance" and "visibility" (or "access") aren't the same thing. The same thing applies to anonymous inner classes. If you use one in a place where the private instance field is visible, then you can refer to the field; if you use it in a place where the private instance field is not visible, then you can't. The location of the class declaration is more important than the type of class (nested/inner/anonymous) for this purpose.
Suppose we take away the static keyword and make it an inner class:
public class Foo1 {
private int bar1;
public Foo1(int x) {
bar1 = x;
}
public class Foo2 extends Foo1 {
public Foo2(int x) {
super(x * 10);
}
public void show() {
System.out.println("bar1 = " + bar1);
System.out.println("((Foo1)this).bar1 = " + ((Foo1)this).bar1);
System.out.println("Foo1.this.bar1 = " + Foo1.this.bar1);
}
}
}
public class Test64 {
public static void main(String[] args) {
Foo1 f1 = new Foo1(5);
Foo1.Foo2 f2 = f1.new Foo2(6);
f2.show();
}
}
Now a Foo2 object is also a Foo1; but since it's an inner class, a Foo2 instance also has an enclosing instance that is a different Foo1 object. When we create our Foo2, it users a superclass constructor to set the superclass bar1 to 60. However, it also has an enclosing instance whose bar1 is 5. show() displays this output:
bar1 = 5
((Foo1)this).bar1 = 60
Foo1.this.bar1 = 5
So just bar1 by itself refers to the field in the enclosing instance.
public abstract class Test {
private static int value = 100;
}
And
public abstract class Test {
private int value = 100;
}
Since Test is abstract, it can't be instantiated, and therefore it doesn't make any difference whether value is static or not, right?
Is there any difference when a field is static or not when it belongs to an abstract class?
Yes, there is. Even thou your class is abstract, it can have non-abstract non-static methods working with non-static private fields. It is usefull sometimes.
Dummy exaple:
Consider following: you want to hold one integer and give everyone the ability to change it, but you dont want them to set negative values, or values bigger then 15, but the condition isn't known (in general) by everyone, so you want to ensure that when someone sets incorect value, it gets fixed automaticly.
Here is one possible solution:
abstract class MyInt {
private int myInt;
public int getMyInt() {
return myInt;
}
public void setMyInt(int i) {
myInt = checkMyInt(i);
}
protected abstract int checkMyInt(int i);
}
Now you can inplement any logic in checkMyInt() and hand over the instance declared as MyInt
pastebin exaplme
PS: this probably isnt the best solution and i would use interfaces here, but as an example it is enought i hope
Abstract classes can't be instantiated directly. But the whole point of abstract classes is to have subclasses that are instantiated:
public abstract class Test
protected int value;
}
public class TestImpl extends Test {
public TestImpl(int value) {
this.value = value;
}
}
In the above example, each instance of TestImpl (and thus of Test) has its own value. With a static field, the field is scoped to the Test class, and shared by all instances.
The difference between static and non-static fields is thus exactly the same as with any other non-abstract class.
An abstract class is a normal (base) class, just declared to be missing some things, like abstract methods.
So there is definite a difference.
I am trying to create an object of the Math in Java. Ideally there is no need of creating such an instance as it only has static methods and parameters. I just want to create it whether it will allow me or not. So when I am creating a math class object, compiler error is displayed saying that the Math class constructor is not visible.
But I looked into the Math class code and there is no explict constructor provided, so java will provide a default constructor, which can be accessed outside.
This is correct behavior. The constructor for Math is private as it only contains static utility methods:
private Math() {}
This is from Java docs.
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
}
The documentation comment itself is sufficient to answer your question.
If you look at the Math class definition, its constructor is private:
private Math() {}
This means that the creator of the class does not want the user to be able to create instances of this class. It makes sense because it's a utility class, which means any method inside the class does not depened on the state of the object. You just need to pass the method parameter values and it will simply give you the intended result. That's why all the methods inside the Math class are static.
You can't do it because its constructor is private. You don't see the constructor in the API because private methods are not listed.
For example take this example:
public class SampleClass {
private static int var1 = 1;
private static int var2 = 1;
private static int var3 = 1;
private SampleClass () {
// This constructor will prevent the default constructor from being invoked
}
public static void runMethod1() {
System.out.println("Value is:" + var1);
}
public static void runMethod2() {
System.out.println("Value is:" + var2);
}
public static void runMethod3() {
System.out.println("Value is:" + var3);
}
}
You can only create an instance of this class from inside the same class. If you try to create it from elsewhere, you will fail.
I've come across some odd behavior in assignment of final variables. You can assign a final varible in a constructor to initialize it, which makes sense. However you can't do the same in a subclass, even if the final variable is a member of the subclass -
public class FinalTest {
public final String name;
public FinalTest()
{
name = "FinalTest";
}
public static class FinalTestSubclass extends FinalTest {
public FinalTestSubclass()
{
name = "FinalTestSubclass"; //<---- this won't compile, assignment to final variable.
}
}
}
Can someone think of a good reason why this should/would work this way?
Every constructor of a subclass must invoke a constructor of the superclass as its first operation. Every final member variable must be initialized before a constructor completes. A final variable can be assigned only once. Given those rules, it is impossible for a subclass constructor to directly assign a value to a final superclass' member.
Making exceptions would increase complexity and create "gotchas" in exchange for limited additional utility.
A practical solution is to provide a superclass constructor that takes a value to be assigned to the final member. This can be protected or package-private if desired. If the superclass is outside of your control, there's a good chance that allowing derived classes to break its assumptions about the finality of its members would cause other problems.
If you were allowed to assign a value to name in FinalTestSubClass it would mean that the value assigned in FinalTest was not actually the final value.
If your example was valid, then this would mean that name could have different values (based upon which class was instantiated), making the final modifier pretty much redundant.
A better question is, why should the behavior you desire be allowed?
informally, final fields should have been initialized when the constructor is finished.
in your subclass constructor, super() has been called implicitly, the constructor of the super class is finished, the final fields in the super class should not be modified.
you may want this instead:
class A
final String s;
A(String s){ this.s = s; }
A() { this("default"); }
class B extends A
B(){ super("B's default"); }
This is standard behavior in Java
The key word final can by used in multiple way, for class close the possibility to inherite from it, for method to override it, for variable allow to be assigned only once in simply words.
For your case this variable is allready assigned in super class,
what You can do is
public class FinalTest {
public final String name = "FinalTest";
public FinalTest()
{
}
public static class FinalTestSubclass extends FinalTest {
public final String name = "FinalTestSubclass";
public FinalTestSubclass()
{
}
}
}
Read more about final variables
In reply to your comment to matt's answer; you can achieve determining the constant in the subclass by passing it in the constructor:
public class FinalTest {
public final String name;
public FinalTest()
{
this("FinalTest");
}
protected FinalTest(String nameConstant)
{
name = nameConstant;
}
public static class FinalTestSubclass extends FinalTest {
public FinalTestSubclass()
{
super("FinalTestSubclass");
}
}
}