I have half a dozen classes which all extend the same abstract class. The abstract class has a static variable pointing to some JNI code that I only want to load once per instantiation of the classes.
From what I understand this results in exactly one instance of this static variable being instantiated, but what I want is for each of the extending classes to have their own static instance of the variable that is unique for the given child class. I want to write some code in my abstract class that modifies and/or releases the abstract class. Is it possible to do both of these things at once?
So as an example can I write an abstract class bar with an variable foo and a printFoo method which prints the content of foo. Then I instantiate in order fooBar1, fooBar2, and fooBar3 which each extend the bar class and initialize foo to different values in static blocks. If I call foobar1.printFoo I want to print the static value of foo initialized by fooBar1 constructor.
Can this be done in java?
You can approximate it, but you will need separate static variables for each subclass, to stop subclasses overwriting each others values. It's easiest to abstract this via a getter getFoo so that each subclass fetches the foo from the right place.
Something like this
abstract class Bar
{
// you don't have to have this in the base class
// - you could leave out the variable and make
// getFoo() abstract.
static private String foo;
String getFoo() {
return foo;
}
public void printFoo() {
System.out.print(getFoo());
}
}
class Foo1 extends Bar
{
static final String foo1;
public String getFoo() {
return foo1; // return our foo1 value
}
public Foo1() {
foo1 = "myfoo1";
}
}
class Foo2 extends Foo1
{
static final String foo2;
public String getFoo() {
return foo2; // return our foo2 value
}
public Foo2() {
foo2 = "myfoo2";
}
}
I have a similar problem. Looks like Java can't isolate static members (attributes). I ended up adding an abstract method instead of the attribute:
public abstract class Abs {
public void printX() {
System.out.println("For " + this.getClass() + " x=" + getX());
}
protected abstract Integer getX();
}
public class A extends Abs {
protected static Integer x = 1;
#Override
protected Integer getX() {
return x;
}
}
public class B extends Abs {
protected static Integer x = 2;
#Override
protected Integer getX() {
return x;
}
}
public class test {
public static void main(String args[]) {
Abs a = new A();
a.printX();
Abs b = new B();
b.printX();
Abs c = new A();
a.printX();
b.printX();
c.printX();
}
}
Related
Consider this example (warning-very bad code):
public abstract class A {
static float foo;
public static void loadfoo(float incomingfoo) {
foo = incomingfoo;
}
public static void displayfoo() {
System.out.println("your foo is" +foo);
}
}
Class B extends Class A
public class B extends A {
static float foo;
//#Override (overide is not allowed for static methods. dis is a problem...)
public static void loadfoo(float incomingfoo){
foo = incomingfoo;
}
}
Class C is pretty much the same as B
public class C extends A {
static float foo;
//#Override
public static void loadfoo(float incomingfoo) {
//I would like a different static variable loaded into this class using this method
foo = incomingfoo;
}
}
finally the main Class runs the thing
public class Main {
public static void main(String whatever[]){
B.loadfoo(5);
C.loadfoo(8);
B.displayfoo();
C.displayfoo();
}
}
so the output of this is :
your foo is0.0
your foo is0.0
and I am aware this is because the displayfoo class reference the static foo in Class A, so please disregard this. I assume I have now been specific enough about describing my problem and goal. solutions anyone?
Edit: I feel like an idiot I completely forgot to actually state what I wanted to accomplish, but really all I want is for B and C to have there own static variables loaded into them without altering A's variable, which should be the default.
It looks like you need static access to two stateful objects with the same structure. In this case, an enum might be a solution:
public enum A {
B, C;
private float foo;
// getter and (optional) setter for foo here
public void displayFoo() { System.out.println("This foo is " + foo); }
}
This way you can still access your object statically, but don't need to duplicate anything else:
A.B.setFoo(5);
A.C.setFoo(8);
A.B.displayFoo(); // 5
A.C.displayFoo(); // 8
If you then need a static default, I would make it a method on A:
enum A {
A getDefault() { return A.B; }
}
A.getDefault().displayFoo();
It seems that first you want to load the values using loadfoo to foo and then display the value of that foo using the displayfoo method. Well, I don't think there is anyway to do it using static methods.You can do this by making displayfoo() method abstract and overriding the same in the subclasses B and C.
Here is the code:
abstract class A {
float foo;
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
public abstract void displayfoo();
}
class B extends A{
#Override
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
class C extends A{
#Override
public void loadfoo(float incomingfoo){
this.foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
public class Main {
public static void main(String whatever[]){
B b = new B();
C c = new C();
b.loadfoo(5);
c.loadfoo(5);
b.displayfoo();
c.displayfoo();
}
}
You can also check the same kind of question here.
Static methods should be used by static method access and not by object instance. It's not supposed to be virtual because it's not belong to the object.
If you call B.loadfoo() then a method of B class is called.
If you call C.loadfoo() then a method of C class is called.
You cannot call a static method if it doesn't exist in the class.
There's no point to use static methods if you want to use polimorphism.
Im very new to programming and want to know if I can somehow get the object from a class where I already used new MyClass(); to use it in another class and that I don't need to use new MyClass(); again. Hope you get the point.
Some very simple example:
class MyFirstClass
{
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass
{
// This is where I want to use the object from class Something()
// like
getObjectFromClass()
}
You can use Singleton pattern to achieve this
This is kickoff example of such object. It has a private constructor and public class method getInstance:
static methods, which have the static modifier in their declarations,
should be invoked with the class name, without the need for creating
an instance of the class
When we make a call to getInstance it checks if an object has been created already and will return an instance of already created objected, if it wasn't created it will create a new object and return it.
public class SingletonObject {
private static int instantiationCounter = 0; //we use this class variable to count how many times this object was instantiated
private static volatile SingletonObject instance;
private SingletonObject() {
instantiationCounter++;
}
public static SingletonObject getInstance() {
if (instance == null ) {
instance = new SingletonObject();
}
return instance;
}
public int getInstantiationCounter(){
return instantiationCounter;
}
}
To check how does this work you can use the following code:
public static void main(String[] args) {
SingletonObject object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
}
Since you have just started coding won't give you a term like reflection and all.. here is one of the simple way is have a public getter() method.
Consider this simple example
class Something {
private int a=10;
public int getA() {
return a;
}
}
Here is the First which has a public method which return the object that i created in this class for the Something Class
class MyFirstClass {
private Something st;
public MyFirstClass() {
this.st = new Something();
}
public Something getSt() {
return st;
}
}
Accessing it from another Class
class MySecondClass {
public static void main(String...strings ){
MyFirstClass my =new MyFirstClass();
System.out.println(my.getSt().getA());
}
}
Output: 10
If You wan't to verify
Inject this function in MyFirstClass
public void printHashcode(){
System.out.println(st);
}
and then print the hash codes from both methods in MySecondClass
class MySecondClass {
public static void main(String...strings ){
MyFirstClass my =new MyFirstClass();
System.out.println(my.getSt());
my.printHashcode();
}
}
You will see that indeed you are using the Object created in MyFirstClass in MySecondClass.
Because this will give you same hashcode output.
Output On my machine.
Something#2677622b
Something#2677622b
Instead of using the Singleton pattern, a better pattern to use is dependency injection. Essentially, you instantiate the class you want to share, and pass it in the constructor of every class that needs it.
public class MainClass {
public static void main(String[] args) {
SharedClass sharedClass = new SharedClass();
ClassA classA = new ClassA(sharedClass);
ClassB classB = new ClassB(sharedClass);
}
}
public class ClassA {
private SharedClass sharedClass;
public ClassA(SharedClass sharedClass) {
this.sharedClass = sharedClass;
}
}
public class ClassB {
private SharedClass sharedClass;
public ClassB(SharedClass sharedClass) {
this.sharedClass = sharedClass;
}
}
Singleton pattern lets you have single instance which is 'globally' accessible by other classes. This pattern will 'guarantee' that you have only one instance in memory. There are exceptions to one instance benefit, such as when deserializaing from file unless care is taken and readResolve is implemented.
Note that class Something right now has no state(fields), only behavior so it is safe to share between multiple threads. If Something had state, you would need to provide some kind of synchronization mechanism in multi thread environment.
Given such stateless Singleton, it would be better to replace it with class that contains only static methods. That is, unless you are implementing pattern such as Strategy which requires interface implementation, then it would be good idea to cache instance like bellow with Singleton pattern.
You should rework your Something class like this to achieve singleton:
public class Something {
private static final Something INSTANCE = new Something ();
private Something () {
// exists to defeat instantiation
}
public Something getInstance() {
return INSTANCE;
}
public void service() {
//...
}
public void anotherService() {
//..
}
}
If FirstClass and SecondClass are somehow related, you can extract that common object you're using to a super class, and that's the only scope in which you're planning to use this object.
public class SuperClass{
Something st = new Something();
public Something getObjectFromClass(){
return st;
}
}
public class MyFirstClass extends SuperClass{
getObjectFromClass();
}
public class MySecondClass extends SuperClass{
getObjectFromClass();
}
Otherwise, if you plan to use that instance somewhere else you should use a
Singleton object. The easiest way of doing this is:
enum Singleton
{
INSTANCE;
private final Something obj;
Singleton()
{
obj = new Something();
}
public Something getObject()
{
return obj;
}
}
You use it:
Singleton.INSTANCE.getObject();
Okay firstly you can use inheritance e.g.
class MyFirstClass
{
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass extends myFirstClass
{
// This is where I want to use the object from class Something()
// like
MySecondClass obj = new MySecondClass();
obj.method(); //Method from myfirstclass accessible from second class object
}
Or if you dont want any objects and just the method you can implement interfaces e.g.
public interface MyFirstClass
{
//example method
public abstract void saying(); //no body required
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass implements MyFirstClass //Have to implement methods
{
public void saying(){ //Method implemented from firstClass no obj
System.out.println("Hello World");
}
getObjectFromClass()
}
So, one friend sent me this code and said that it had compiled successfully and returned 42.
But, the bothering thing is the method in parent class that "returns" 42 is private, and the method that is called on is in child class, and it's public. So, can anybody tell why and how this works?
static class A {
private int f() {
return 42;
}
}
static class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
It returns 42.
I tried to get rid of static, and
class A {
private int f() {
return 42;
}
}
class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
Main m= new Main();
B b= m.new B();
System.out.print(b.f2());
}
it still returns 42.
Since both of the classes (A and B) are nested in Main, they can access the private int f() method.
If you extract the sources of A and B in top-level classes, this won't happen and you'll fail to compile.
The point of private is that "outside" classes should not be able to see private variables. But A and B are both part of the same class, or are nested within each other, so they can access each others private members.
So this will work:
public class A {
private void a() {
int bVal = this.new B().val; //! Accessing B private
}
class B {
A a = new A();
private int val = 10;
public void b() {
a.a(); // !! Accessing A private
}
}
BUT, this will fail, even if both A and B are in the same file but not within each other:
class A {
private void a() {}
}
class B extends A {
A a = new A();
public void b() {
a.a(); // can't see even if B extends A
}
}
This is because both classes A and B are nested inside another class, i.e both classes are inner classes of (or "part of") another same class. Since they (Data Members and Methods) are basically a member of the outer class,they are accessible within other inner classes even if private.
Java allows us Nesting of classes,If You Don't know about nested classes first read this :
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
class Outer{
class A {
private int f() {
return 42;
}//Method f() is a private member of A and accessible by Outer
}
class B extends A {
public int f2() {
return super.f();
}//As class B is inner class of Outer it can access members of outer,thus indirectly member of A
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
}
I am implementing my first Decorator pattern. The base class which I want to decorate has a member variable initialized in the constructor. The decorated class also has this member variable (since it is a descendant of the base class). My question is, should I initialize this member variable in the decorated class too, or use the member variable of the base class (which lives inside the decorated class)?
Here is some code. I'm just curious whether Decorated1 or Decorated2 is better?
public class Base{
private String memberVariable;
public Base(){
memberVariable = "";
}
public Base(String s){
memberVariable = s;
}
public String Description(){
//code here
}
}
public abstract class BaseDecorator(){
public abstract String Description();
}
public class Decorated1 extends BaseDecorator{
Base b;
public Decorated1(Base _b){
b = _b;
}
public String Description(){
//code here
}
public String getMemberVariable(){
return b.getMemberVariable();
}
}
public class Decorated2 extends BaseDecorator{
Base b;
public Decorated1(Base _b){
super(_b.getMemberVariable());
b = _b;
}
public String Description(){
//code here
}
public String getMembervariable(){
return memberVariable;
}
}
You have to figure out what this variable means for your class, or if it is really needed, but i would suggest that no.
interface IObject{
//declare methods
void doSomething();
}
class ObjectA implements IObject{
private int variable;
public void doSomething(){
}
}
class DecorateObject implements IObject {
private IObject decoratedObject;
public void doSomething(){
decoratedObject.doSomething();
//do more things
}
}
if IObject is a drawable element, it would have x,y coordinates that would be inherited so it is correct to put on a superclass, in this case it would be an abstract class.
interface IObject{
//declare methods
}
abstract class AbstractObject implements IObject{
private int xCoordinate;
}
class ObjectA extends AbstractObject {
}
class DecorateObject extends AbstractObject {
private IObject decoratedObject;
}
I'm not sure if my question title describes my situation aptly, so my apologies if it doesn't! Anyway, let's say I have the following code snippet (visibility is as stated):
public class ChildClass extends ParentClass {
// more code
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
// insert code to access a method in ParentClass
}
};
}
}
Is it possible for code within anotherMethod() to access a protected method found in ParentClass? If so, how can this be done?
I've tried something like...
(ParentClass.this).parentMethod();
...but obviously it doesn't work due to scope issues.
This compiles fine:
class MyClass {
}
class ParentClass {
protected void parentMethod() {
}
}
class ChildClass extends ParentClass {
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
parentMethod(); // this works
}
};
}
}
A non-static inner class can access all methods of the enclosing class as if it were it's own methods:
public class Test {
public int getOne() {
return 1;
}
public class Inner {
public int getEnclosingOne() {
return getOne(); // this works...
}
}
}
A static inner class can not, as a static inner class is not bound to an instance of the parent class. That can only call static methods on the enclosing class.
As for methods when taking into account inheritance, an method in a non-static inner class can use all the methods of the enclosing (outer) class.
The interesting part is Test2.super.getOne() which indeed obtains getOne() from Test2.super, which is a Test. This is just like Test2 would access the method, namely using super though prefixed with Test2 to indicate you're accessing the namespace of the outer class.
public class Test2 extends Test {
public int getInnerOuterParentOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterParentOne();
}
public int getInnerOuterOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterOne();
}
public int getOne() {
return 2;
}
public class Inner2 {
public int getOuterOne() {
return getOne();
}
public int getOuterParentOne() {
return Test2.super.getOne();
}
}
public static void main(String[] args) {
Test2 test2 = new Test2();
System.out.println(test2.getInnerOuterOne()); // 2
System.out.println(test2.getInnerOuterParentOne()); // 1
}
}
There is no way to access "parent class method" in Java, irrelatively to visibility (except for super.parentMethod() in subclass's parentMethod()).
That is, if ChildClass overrides parentMethod(), there is no way to call ParentClass.parentMethod() (bypassing ChildClass.parentMethod()) from other methods of ChildClass.
However, if ChildClass doesn't override parentMethod(), that method is inherited by ChildClass, so that you can access it as a ChildClass's method, i.e. simply as parentMethod().