public enum Parent {
item1(1){
public void testing() {
add();
multiply();
minus(); // error here!!!
}
}, item2(2);
private int i ;
Parent(int i){
this.i = i;
}
public void setI(int i ){
this.i = i;
}
public int getI(){
return i;
}
public void multiply(){
}
protected void add(){
}
private void minus(){
}
}
As you guy can see, they are in the same class, how come minus() cannot be used internally? Usually inner class can access private method/field in the outer class right?
To be able to access minus() from item1, you have to make it protected (or public).
The correct way to think about Parent and item1 is as a base class and a subclass.
From the JLS:
The optional class body of an enum constant implicitly defines an anonymous class declaration (ยง15.9.5) that extends the immediately enclosing enum type.
Actually what happens is when you provide implementation while creating enum object, you are basically extending the Parent class with an extra method i.e. Annonymous implementation. So it does not allow to access private method of Parent class but allows protected and public.
enum A{
a{
#Override
public void method() {
// TODO Auto-generated method stub
super.method();
}
};
public void method(){
}
}
This should explain see the #Override annotation provided by eclipse.
The problem is that "item1" is not an inner class of Parent, it's in fact top level class. To verify see generated class for item1, it is Parent$1.class, if it was an inner class it would be Parent$item1.class
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am new to java and I have few basic questions:
What memory does a Static variable / method use ?
Does the keyword 'Super' have significance only in scenarios of Method overriding ?
Keyword super can be used for:
Declaring a generic type:
public class Foo<E super Bar> { // <=====
...
}
Calling base class constructor from subclass constructor:
public class Bar {
private int id;
public Bar(int id) {
this.id = id;
}
}
public class Foo extends Bar {
public Foo(int id) {
super(id); // <=====
}
}
Access a field in a base class, when subclass has hidden the field:
public class Foo extends Bar {
private int id;
public int getFooId() {
return this.id;
}
public int getBarId() {
return super.id; // <=====
}
}
Calling base class method from overridden subclass method:
public class Bar {
public void doGreatWork() {
...
}
}
public class Foo extends Bar {
#Override
public void doGreatWork() {
...
super.doGreatWork(); // <=====
...
}
}
Referencing base class method when subclass has overridden the method
public class MultiBar extends Bar {
public void doGreatWork() {
list.stream().forEach(super::doGreatWork); // <=====
}
}
To access the data members of parent class when both parent and child class have member with same name, to explicitly call the no-arg and parameterized constructor of parent class, to access the method of parent class when child class has overridden that method.It can be used to access the variables of parent class, to invoke constructor of parent class and can be used in case of method overriding.
What memory does a Static variable / method use ?
if we want to access or call the method, we don't need to create object, simply we can use static keyword while writing method like ->> public static show().
when we use the static keyword the class will be called and executed the method.
the static means we can't change the value , we can use static keyword to variables also, once we use static keyword that means we cant change the values often.
example:
public class static example
{
public static void main(String[] args)
{
xyz.i = 10;
xyz.show();
}
}
class xyz
{
static int i;
public static void show()
{
System.out.println("Stackoverflow example by Me");
}
}
Does the keyword 'Super' have significance only in scenarios of Method overriding ?
when we want to call the method from parent class, the child class method will be executed in method overloading, because the parent and child classes will have same method name. that's why the method overloading happens. to overcome this problem we use super keyword to call the parent class method even having parent class and child class same name. we can easily call and execute parent class method
example:
class A {
int i;
public void show(){
System.out.println("A");
}
}
class B extends A {
int i;
public void show(){
super.show()
System.out.println("B");
}
}
public class overriding example {
public static void main(String[]args) {
B obj1 = new B();
obj1.show();
}
}
I have an identical method that is repeated in every subclass and I'd like to refactor it to just one method in a superclass.
public class SubClass1 extends SuperClass {
private BoltHexHead bolt;
private void computeFoo() {
//Foo formula is identical in all subclasses. Need to move up
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
private void computeBar() {
//computeBar method in all subclasses but Bar formula is different amongst all subclasses
setBar(bolt.getDiameter() - 2*bolt.getPitch() - 3*bolt.getTpi());
}
private void computeSeparation() {
//computeSeparation method only exists for a Subclass 1
setSeparation(bolt.getLength() - 2*nut.getFlatDia());
}
public class SubClass2 extends SuperClass {
private BoltFlatHead bolt;
private void computeFoo() {
//Foo formula is identical in all subclasses. Need to move up
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
private void computeBar() {
//computeBar method here is different than in Subclass1
setBar(bolt.getDiameter() - 4*bolt.getPitch() - 1/3*bolt.getTpi());
}
private void computeProtrusion() {
//computeProtrusionmethod only exists for a Subclass 2
setProtrusionmethod(bolt.getThreadAngle() - 6*bolt.getTpi());
}
Initially I posted that bolt wasn't getting set in the SuperClass but was in the SubClass. What I got working after my initial post was the following
public abstract class SuperClass {
protected Bolt<?> bolt; <-- this was added but uses wildcard
...bolt getters/setter
protected void computeFoo() {
//Foo formula pulled up from all subclasses
setFoo(bolt.getDiameter() + bolt.getPitch() + bolt.getTpi());
}
}
public class SubClass1 extends SuperClass {
//private BoltHexHead bolt; <-- commented this out in each subclass
}
This is a JSF app and in each controller bean I instantiate the specific joint attribute subclass and then set the specific bolt. It was an earlier design decision to use setters for setting the bolt (and other properties) in the subclass rather than doing it with the Constructor; but one refactor at a time.
Controller for a Bolt Analysis using a HexHead Bolt
private SubClass1 sc1 = new SubClass1();
private BoltHexHead bolt;
sc1.setBolt(bolt);
sc1.computeResults();
Controller for a Bolt Analysis using a FlatHead Bolt
private SubClass2 sc2 = new SubClass2();
private BoltFlatHead bolt;
sc2.setBolt(bolt);
sc1.computeResults();
So my question is, is it OK to use wildcard Bolt<?> bolt or is there a better approach?
I'm just trying to put a identical/duplicate method from all my subclasses into the parent but one of the variables (bolt) isn't getting set
Thats because in java you cannot override fields.
So your variables "private B bolt;" in your superclass and "private BoltHexHead bolt;" in your subclass are two different things. They actually both exist at the same time.
What you are trying to do actually isn't that complicated. You just need to clean up your code:
Only define "private B bolt;" and its setters/getters once in your superclass.
Only use those getters/setters to access bolt
If you want your subclass to have a "bolt" of the type "BoltHexHead" then define the generic parameter as such in the class definition ("extends JointAttribute<BoltHexHead>" instead of "extends JointAttribute<Bolt<BoltSpec>>")
A simple example for demonstration purspose:
Superclass:
public class Superclass<T> {
private T value;
protected T getValue() {
return value;
}
protected void setValue(T value) {
this.value = value;
}
protected void print() {
if(getValue()==null) {
System.out.println("NULL");
} else {
System.out.println(getValue().toString());
}
}
}
Subclass1:
public class Subclass extends Superclass<String> {
public Subclass() {
}
public static void main(String[] args) {
Subclass subclass= new Subclass();
subclass.print();
subclass.setValue("test");
subclass.print();
}
}
Subclass2:
public class Subclass2 extends Superclass<Integer> {
public Subclass2() {
}
public static void main(String[] args) {
Subclass2 subclass= new Subclass2();
subclass.print();
subclass.setValue(3);
subclass.print();
}
}
I have an abstract class that should implement a public field, this field is an interface or another abstract classe.
something like this:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extends GenericChild {
public int prop1=2;
}
Now i have another specialized class Container:
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
Java allow me to compile this, and i IMAGINE that the field child in SpecialContainer is automatically overloading the field child of the GenericContainer...
The questions are:
Am i right on this? The automatic 'overloading' of child will happen?
And, more important question, if i have another class like this:
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
test() will return 1 or 2? i mean the GenericContainer container field what prop1 will call, the generic or the special?
And what if the special prop1 was declared as String (yes java allow me to compile also in this case)?
Thanks!
In Java, data members/attributes are not polymorphic. Overloading means that a field will have a different value depending from which class it's accessed. The field in the subclass will hide the field in the super-class, but both exists. The fields are invoked based on reference types, while methods are used of actual object. You can try it yourself.
It's called, variable hiding/shadowing, for more details look on here
It isn't overriding anything, you're just hiding the original field at the current class scope. If you use a variable with the subtype you will still be able to access the original property. Example:
abstract class GenericContainer {
public GenericChild child;
}
abstract class GenericChild {
public int prop1=1 ;
}
class SpecialChild extends GenericChild {
public int prop1=2;
}
class SpecialContainer extends GenericContainer {
public SpecialChild child;
}
public class Main {
public static void main( String ... args ) {
GenericContainer container = new SpecialContainer();
container.child = new SpecialChild();
System.out.println( container.child.prop1 );
SpecialChild child = (SpecialChild) container.child;
System.out.println( child.prop1 );
}
}
This prints 1 and then 2.
From SpecialChild you would also be able to go up one level using super:
class SpecialChild extends GenericChild {
public int prop1=2;
public int getOriginalProp1() {
return super.prop1;
}
}
Regarding
....and i IMAGINE that the field "child" in SpecialContainer is automatically overloading the field 'child' of the GenericContainer...
No. Fields don't get overridden, only methods do.
This is one reason why use of (overridable) getter and setter methods are preferred to direct access to fields. Your fields should almost all be private.
As for your design, there's no need for your SpecialContainer class to have a SpecialChild field, but instead the SpecialChild object should be placed in the GenericChild field.
Why nobody is observing that program will throw NullPointerException.
subclass's field with same name will hide super class's field. There is no overriding with field. Overriding is only possible with methods.
Original Code by Author:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extend GenericChild {
public int prop1=2;
}
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
Java allow me to compile this, and i IMAGINE that the field "child" in
SpecialContainer is automatically overloading the field 'child' of the
GenericContainer...
Firstly, Inheritence doesn't apply to variables. Fields(Insatnce variables) are not overridden in your sub-class.they are only visible in your subclass if they are marked with either public, protected or default.
To answer your question it maintains both instances. And depending on how you refer to the container (either through the abstract or the impl) determines which variable you are referring to.
public class Test {
public abstract class Container{
public Generic gen = new Generic();
}
public class ContainerImpl extends Container{
public GenericImpl gen = new GenericImpl();
}
public class Generic{
public int prop = 0;
}
public class GenericImpl extends Generic{
public int prop = 1;
}
public Test(){
Container c = new ContainerImpl();
System.out.println(c.gen.prop); // Outputs "0"
System.out.println(((ContainerImpl)c).gen.prop); // Output "1"
}
public static void main(String[] args) {
new Test();
}
}
The bigger question at hand is, why would you design something like this? I'm assuming you are asking from a theoretical perspective.
My 2 cents, this isn't great OO design. You would be better off making the public variables private and assigning their values through a constructor or property setter. As-is, it will lead to unexpected results in your code.
So I've come across a bit of a snag in some code that I'm working with. Essentially I have the following three tidbits of code:
Abstract class:
public abstract class TestParent {
int size;
public TestParent(int i){
size = i;
}
}
Child Class:
public class TestChild extends TestParent{
public void mult(){
System.out.println(this.size * 5);
}
}
Implementation:
public class TestTest {
public static void main(String args[]) {
TestChild Test = new TestChild(2);
Test.mult();
}
}
Consider the following case of abstract class and extends implementation.
https://stackoverflow.com/a/260755/1071979
abstract class Product {
int multiplyBy;
public Product( int multiplyBy ) {
this.multiplyBy = multiplyBy;
}
public int mutiply(int val) {
return muliplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a default constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.
NOTE: As there is no default (or no-arg) constructor in the parent abstract class the constructor used in subclasses must be specified.
Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.
public class TestChild extends TestParent{
public TestChild(int i){
super(i); // Call to the parent's constructor.
}
public void mult(){
System.out.println(super.size * 5);
}
}
Use super to call parent (TestParent.TestParent(int)) constructor:
public class TestChild extends TestParent{
public TestChild(int i) {
super(i);
}
//...
}
or if you want to use some constant:
public TestChild() {
super(42);
}
Note that there is no such thing as abstract constructor in Java. Essentially there is only one constructor in TestParent which must be called before calling TestChild constructor.
Also note that super() must always be the first statement.
When you have explicit constructor defined in super class and no constructor without arguments defined, your child class should explicitly call the super class constructor.
public class TestChild extends TestParent{
TestChild ()
{
super(5);
}
}
or, if you don't want call super class constructor with parameters, you need to add constructor with no arguments in super class.
public abstract class TestParent {
int size;
public TestParent(){
}
public TestParent(int i){
size = i;
}
}
You code wont compile because your base class does not have a default constructor. Either you need to provide it in base class or you need to provide parameterized constructor in derived class and invoke super.
public class TestChild extends TestParent{
public TestChild (int i)
{
super(i * 2);
}
}
This code would use the double of i. This is an overriding, though i'm not sure what you want to ask.
Other solution:
public class TestChild extends TestParent{
public TestChild (int i)
{
super(i);
this.size = 105;
}
}
For this solution, size must be protected or public.
I have a java program which uses arraylists - these arraylists store 'variables' where 'variables' is an abstract class.
Now, to save memory, I want to use a java library called HugeCollections-VanillaJava- however this library requires an interface to be defined.
How do I convert the abstract class into an interface? What rules/restrictions do I have to follow, to correctly perform the conversion?
Finally, is it possible for me to use my abstract class with minimal code changes, so that the library that requires an interface, also works correctly? Ideally I would like not to change the abstract class at all...Is this possible?
how do I convert an abstract class into an interface?
Make a copy of the abstract class source file.
Change "class" to "interface" in the initial declaration.
Change the name (optionally, depends on what you're doing).
Remove the bodies of any methods that are implemented by the class.
Remove the word "abstract" from the other ones.
Remove all private and protected members.
Remove all constructors.
Remove the keyword "public" from the public members.
If you had any code you removed (implemented methods, private or protected stuff), have your original abstract class implement your interface and leave that stuff there.
(Incomplete) Example:
Foo as an abstract class:
public abstact class Foo
{
private int bar;
public static final int SOME_CONSTANT = 42;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
Foo as an interface:
public interface Foo
{
int SOME_CONSTANT = 42;
void doSomething(String s);
}
In my case, as I did have some stuff the old Foo did, I'd probably have AbstractFoo or something:
public abstact class AbstractFoo implements Foo
{
private int bar;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
...so that an implementation could use it as a starting point if desired (although with that private bar in there, it doesn't make a lot of sense).
Pattern Adapter might help you.
Imagine, you're have to use SomeClass as TargetInterface
public abstract class SomeClass {
// some code here
public abstract void someMethod();
}
public interface TargetInterface {
public void someMethodBlaBla();
}
And they have different signatures of methods - someMethod() and someMethodBlaBla().
So you're might create such adapter class:
public class Adapter implements TargetInterface {
private SomeClass adaptee;
public Adapter( SomeClass adaptee ) {
this.adaptee = adaptee;
}
public void someMethodBlaBla() {
this.adaptee.someMethod();
}
//delegate all calls to adaptee
}
and somewhere in code you might use both - adapter and instance of abstract class, without interference on current code:
SomeClass abstractClassInstance = ... //get instance of your abstract class
TargetInterface targetInterfaceInstance = new Adapter( abstractClassInstance );
If abstract class does not define any concrete methods, you can even use regular expression for that. From:
public abstract class Abstract {
public abstract void method();
//...
}
to:
public interface Interface {
void method();
//...
}
public abstract modifiers are implicit for interfaces. If the abstract class does define some methods (not all methods are abstract) or have some fields this can't be done (at least easily).