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();
}
}
Related
This question already has answers here:
Initialize field before super constructor runs?
(7 answers)
Closed 4 years ago.
So, I'm trying to design a small base abstract class:
public abstract class BaseClass
{
abstract void reload();
protected BaseClass()
{
reload();
// schedule reload for every X minutes
}
}
Now, subclass:
class SubClass extends BaseClass
{
private int member = 5;
#Override
void reload()
{
member = 20;
}
}
Now, the problem I'm facing is that reload() method is called before the member is initialized. Thus, member is assigned 20 and afterwards, assigned with the value 5. (this is only an example of course, the actual code is different, but the same idea).
What is the best design for what I'm trying to achieve?
I want the order of the initialization to be - member assigned 5, and if reload() fails for some reason i want it to stay with the initial value. However in this code, 5 overrides the value of reload(). If I don't assign an initial value for the instance member, it works of course.
Is it possible what I'm asking?
Override the constructor and call reload() there but do not call super(), this might not be acceptable for other reasons :)
class SubClass {
private int member = 5;
public SubClass() {
reload();
}
...
}
You can use a builder to achieve that.
This way you can achieve full control.
public abstract class Foo {
public abstract void postConstruct();
public static void main(String[] args) {
Bar bar = Foo.build(Bar.class);
System.out.println(bar);
}
public static <T extends Foo> T build(Class<T> clazz) {
T obj;
try {
obj = clazz.newInstance();
obj.postConstruct();
return obj;
} catch (Exception e) {
throw new IllegalArgumentException(
"Class "+clazz.getName()+" is not a valid class",e);
}
}
}
public class Bar extends Foo {
int value = 10;
protected Bar() {
super();
}
public void postConstruct() {
value = 7;
}
#Override
public String toString() {
return "Bar [value=" + value + "]";
}
}
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.
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
I need to refactor class extracting abstract superclass.
E.g.
UpperClass {
NestedClass {
UpperClass.this.someMethod();
}
}
Like:
AbstractUpperClass {
NestedClass {
?????.this.someMethod();
}
}
After I plan inherit AbstractUpperClass in 2 classes UpperClass1 and UpperClass2.
But I don't know how to refactor this inner class because it inovokes method of enclosing class. Does it possible?
Thanks.
The trick here is knowing how the inner class works. It's essentially just a "normal", static class, but whose constructor implicitly gets a reference to the enclosing class. So, this:
public class TopLevel {
public void go() {
new Inner().bar();
}
public void foo() { }
public class Inner {
public void bar() {
TopLevel.this.foo();
}
}
}
is equivalent to this:
public class TopLevel {
public void go() {
new Inner(this).bar(); // explicitly passing in "this"
}
public void foo() { }
public static class Inner {
private final TopLevel parent; // note that we have this new field
public Inner(TopLevel parent) { // note this new constructor
this.parent = parent;
}
public void bar() { // we use the explicit reference instead
parent.foo(); // of the implicit TopLevel.this
}
}
}
So, with all that said, the way to refactor your inner class to be a top-level class is to add an explicit field referencing the UpperClass instance, and passing this reference into the NestedClass constructor. In other words, be like that second code snippet instead of the first.