Can't call instance method of derived inner class - java

public class A extends Q implements T {
public class B extends Z {
public void D(int A, int B) {
}
}
private Z z;
public A() {
// other stuff
z = new B(/** params **/);
// more stuff
}
void C () {
((B)z).D(2,3);
}
}
The code is structured like that (can't give the full snippet due to legal reasons) When I try to call D, I get symbol not found error from java compiler. Z, Q, and T are defined in different files and they do compile without error.

Okay, if you have a class vehicle(Z) and a class truck(B) which is also a vehicle but can attachCargo(D). Then if we know we have any vehicle(z) and we just assume its a truck ( (B z) ), we cannot know for sure if it actually can attachCargo since we just assumed it were a truck(B). What you could do is create a constructor that takes in a vehicle(Z) and constructs a truck(B) from the information given. This new truck can be treated like a vehicle since it is one, but as we know it is a truck, we can also treat it like a truck:
class AClass extends Q implements T
{
class B extends Z
{
boolean CargoAttached;
public B()
{
}
public B(Z z)
{
CargoAttached = false;
}
public void D(int A, int B)
{
}
}
private Z z = new Z();
void C()
{
z = (new B(z));
((B) z).D(1, 2);
}
}
Which works perfectly fine

Related

Function the uses an object relying in two different packages

I have the sama java object TestData in to packages (A & B). I have made a function that processes the object for a standard business functionality.
CommonFunc.java:
import A.TestData ;
class CommonFunc
{
/// .....
public static TestData processTestData(Date d1, String s1){
TestData testData = new TestData ();
/// set some testData porperties based on d1 and s1
/// e.g : testData.setInitialDate(d1);
return testData ;
}
}
The problem here is that the compiler has to load the object from one of the packages lets say package (A), so when I expect the data to be returned to a local variable from package (B) I get incompatible type error :
File using B TestData and needs to call the function processTestData:
import B.TestData;
// ...
TestData obj = CommonFunc.processTestData(new Date(), "test");
// ...
Is there a way to overcome this problem keeping a common function for both?
Is there a way to overcome this problem keeping a common function for both?
No and yes. On the general case, you cannot.
But you can, IFF you can make the two classes adopt the same interface, with the common methods declared in the same interface. See below, with apologies for the change in the class names:
interface C {
public Date getA();
public void setA(Date a);
}
interface C_Factory <X extends C> {
X createInstance();
}
class C1 implements C {
Date a;
int b;
public C1() {
super();
}
public Date getA() { return a; }
public void setA(Date a) { this.a = a; }
public int getB() { return b; }
public void setB(int b) { this.b = b; }
}
class C2 implements C {
Date a;
float b;
public C2() {
super();
}
public Date getA() { return a; }
public void setA(Date a) { this.a = a; }
public float getB() { return b; }
public void setB(float b) { this.b = b; }
}
public class CommonFunc {
// You need this extra param to create instances----
// V
static <X extends C> X doSomething(Date d, Class<X> clazz)
throws InstantiationException, IllegalAccessException
// You'll have to accept those exceptions as well
{
// the next statement uses clazz as a factory for new X instances
// As such, you can abstract the method further and use
// a custom Factory class instead.
X toret=clazz.newInstance();
toret.setA(d);
// something else
return toret;
}
// A custom factory variant of the above
static <X extends C> X doSomething(Date d, C_Factory<X> factory)
{
X toret=factory.createInstance();
toret.setA(d);
// something else
return toret;
}
static public void main(String[] args) {
try {
C1 c1=doSomething(new Date(), C1.class);
C2 c2=doSomething(new Date(), C2.class);
} catch (InstantiationException | IllegalAccessException e) {
// Should not happen
e.printStackTrace();
}
}
}
I do not see how it is possible in the above example you have posted, The best way out is to make the TestData an interface and have implementations in 2 packages. Then, to decide whether to return A TestDataImpl or B TestDataImpl, take another parameter in the processData, for simplicity, let us say a boolean. Based on true or false instantiate A TestDataImpl or B TestDataImpl and return the same. Where the return type of processData is the interface type
This is probably would be the most straightforward way of reusing the processData method.

Always execute method after constructor in Java

I have a situation where I always need to run a certain bit of code that depends on the object itself
public abstract class A{
public A(X x){
//init A stuff
x.getAList("stuff").add(this);
x.getAList("otherstuff").add(this);
}
}
public class B extends A{
public B(X x){
super(x);
//init B stuff
}
}
public class C extends A{
public C(X x){
super(x);
//init C stuff
x.getAList("otherstuff").remove(this);
x.getAList("morestuff").add(this);
}
}
public class SomeClass{
private X someX;
public A somefunc(boolean b){
if(b){
return new B(someX);
}else{
return new C(someX);
}
}
}
The problem is the following. In this example I use this in the constructor. If another thread tries to access the object through someX.getAList, it could cause that thread to get access to the object before the constructor has ended.
You could make it so that the object gets added to the AList by somefunc
public class SomeClass{
private X someX;
public A somefunc(boolean b){
A a;
if(b){
a = new B(someX);
someX.getAList("stuff").add(a);
someX.getAList("otherstuff").add(a);
}else{
a = new C(someX);
someX.getAList("stuff").add(a);
someX.getAList("morestuff").add(a);
}
return a;
}
}
The problem is that B's and C's could also be instantiated elsewhere and that everytime a B or C is created they would need to be added in that specified way. I don't want adding the object to the AList to be the responsibility of the user, but of the class. I also don't want the user to have to call an init function that does this for them. On the other hand, I don't want any concurrency issues.
Is there a way or a pattern that makes it possible to implement this?
Golang has something like defer that lets you run a piece of code after the function/method/constructor is done.
Make a Factory-Method for the super and subclass instead and make the constructors private, forcing everyone who wants an instance to use the factory method. A factory method is a method that returns a completely constructed instance. Once the instance is completely constructed (after the constructor was called in the factory method) add the instance to the list, that way no thread can get hold of a incomplete/non-finalized instance.
The point of the Factory-Method is to strictly isolate all the initialisation code from any non-initialisation code, to avoid access to and exposure of uninitialised fields. Also it can serve as a selector for users, automatically returning a suitable (sub-)type, without having to be specified.(Interesting design-patterns)
abstract class A{
protected A(){
//constructor code goes here
}
public void afterFinalisation(final X x) {
x.getAList("stuff").add(this);
x.getAList("otherstuff").add(this);
}
}
class B extends A{
protected B(){
super();
//constructor code goes here
}
public static B create(final X x) {
final B returnValue = new B();
returnValue.afterFinalisation(x);
return returnValue;
}
}
class C extends A{
protected C(){
super();
//constructor code goes here
}
#Override
public void afterFinalisation(final X x) {
super.afterFinalisation(x);
x.getAList("otherstuff").remove(this);
x.getAList("morestuff").add(this);
}
public static C create(final X x) {
final C returnValue = new C();
returnValue.afterFinalisation(x);
return returnValue;
}
}
class SomeClass{
private final X someX = new X();
public A somefunc(final boolean b){
if(b){
return B.create(this.someX);
}else{
return C.create(this.someX);
}
}
}
The credit for the constructor code goes to coolcats iteration of my answer, I was trying to avoid putting code into the protected constructors and worked with a init() method instead, which required a big unelegant-workaround for final fields.
By taking a few design decisions from HopfullyHelpful I end up with liking the following design best:
public abstract class A{
protected A(X x){
//constructor with all inits
}
protected A publish(X x) {
x.getAList("stuff").add(this);
x.getAList("otherstuff").add(this);
return this;
}
}
class B extends A{
protected B(X x){
super(x);
//constructor with all inits
}
protected B publish(X x) {
super.publish(x);
return this;
}
public static B create(X x) {
return new B(x).publish(x);
}
}
class C extends A{
protected C(X x){
super(x);
//constructor with all inits
}
protected void publish(X x) {
super.publish(x);
x.getAList("otherstuff").remove(this);
x.getAList("morestuff").add(this);
return this;
}
public static C create(X x) {
return new C(x).publish(x);
}
}
class SomeClass{
private X someX;
public A somefunc(boolean b){
if(b){
return B.create(this.someX);
}else{
return C.create(this.someX);
}
}
}

Inheritance and static type java

I was playing around with classes since I'm learning java syntax and I came across this weird situation. So given a class A and B:
public class A {
public int x() {
return x;
}
}
public class B extends A {
int x = 5;
public int x() {
return x + 2;
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.x());
}
When I execute the main method I get a compile time error that it doesn't find the x variable and it's calling the method from A because the error shows return x instead of return x + 2. Since b's static type is B, why is it looking in A for x?
error: cannot find symbol
return x;
symbol: variable x
location: class A
The class A doesn't know that it will be extended by B, where the x variable will exist.
In order to make this compile, make A.x() abstract and provide implementation within the subclass:
public abstract class A {
public abstract int x();
}
public class B extends A {
int x = 5;
#Override
public int x() {
return x + 2;
}
..
}
When you are creating the Object of class B, it automatically invoke the x() of class A, But x is not initialized in that class. As it is a local variable, it can not be used without initialization. so it is giving an error.
Try the below code, it is working correctly
class A
{
int x =10;
public int x()
{
return x;
}
}
class B extends A
{
int x = 5;
public int x()
{
return x + 2;
}
public static void main(String[] args)
{
B b = new B();
System.out.println(b.x());
}
}

A Java interface to enforce by design the output type of unknown methods of its implementors?

At present, I've defined an empty interface X that is implemented by some other interfaces (just to identify them elsewhere).
All interfaces that implement X may provide as many public methods as they wish, but I want to enforce by design/by architecture, that all of them (note again that they are unknown to X) will return a type that is derived from the same abstract class Y.
Ist their any way I can do this in Java?
In the following example, X should enforce that only types derived from Y are returned by U and V.
public interface X {
// I'm empty at present.
}
public interface U extends X {
public A getA();
public B getB(String bIn);
}
public interface V extends X {
public C getC(Integer cIn);
public D getD(); // Compile should fail!
}
public class A extends Y {
}
public class B extends Y {
}
public class C extends Y {
}
public class D {
// D does *not* extend Y.
}
There is no way to enforce this with the java type system. You would therefore be left with:
reflection
customised static analysis
code reviews & developer education
I would stay away from reflection and static analysis. You haven't said what problem you are trying to solve with this, so it's difficult to give any alternate approaches.
I agree with #fge that this sounds like an XY problem, but I think you might be able to get something to work at compile-time.
You want to place a requirement on every method of a type, but Java only lets you specify that there exist some methods satisfying some requirements on a type, so you will have to refactor U and V.
In the set-up, I've made X specify that any implementors must provide a way to return a Y descendent. I've also specified that Y is an abstract class.
interface X {
Y getY();
}
abstract class Y {
}
Then, I looked at your interfaces U and V, and their methods U#getA(), U#getB(String), V#getC(Integer), V#getD(). All of these methods can be put in their own class.
class UA implements X {
public A getY() {
...
}
}
class UB implements X {
private final String s;
public UB(String s) {
this.s = s;
}
public B getY() {
...
}
}
class VC implements X {
private final Integer integer;
public VC(Integer integer) {
this.integer = integer;
}
public C getY() {
...
}
}
// COMPILE-TIME ERROR
class VD implements X {
public D getY() {
...
}
}
Now, anything that implements X must provide Y. The problem now is that UA, UB, VC, and VD can offer other methods. You've said you only want them to provide methods that return Y. To get around this, you can replace X with a final concrete class, which only provides a single constructor that you control.
Replace X with YFactory (everywhere in the code)
interface YFactory {
Y getY();
}
Now, specify X as a concrete class which only has one constructor:
final class X {
private final YFactory yFactory;
public X(YFactory yFactory) {
this.yFactory = yFactory;
}
public Y getY() {
return yFactory.getY();
}
}
All together:
final class X {
private final YFactory yFactory;
public X(YFactory yFactory) {
this.yFactory = yFactory;
}
public Y getY() {
return yFactory.getY();
}
}
abstract class Y {
}
interface YFactory {
Y getY();
}
class A extends Y {
}
class B extends Y {
}
class C extends Y {
}
class D {
// D does *not* extend Y.
}
class UA implements YFactory {
public A getY() {
return null;
}
}
class UB implements YFactory {
private final String s;
public UB(String s) {
this.s = s;
}
public B getY() {
return null;
}
}
class VC implements YFactory {
private final Integer integer;
public VC(Integer integer) {
this.integer = integer;
}
public C getY() {
return null;
}
}
class VD implements YFactory {
public D getY() {
return null;
}
}
Now you know that any X only has methods that return Y.

How do I control visibility to field in my Java classes?

How can I differentially control access to members of any class? Let's say I have three classes:-
Class A
{
int a;
int b;
}
Class B
{
Access to only 'a' and not 'b'
}
Class C
{
Access to only 'b' and not 'a'
}
One way would be to use aspect-oriented programming. You can check to see the accessing package or class and prohibit access.
AspectJ can be used to enforce that classes in the persistence tier are not accessed in the web tier, only from the service tier. Here's an example:
http://blog.jayway.com/2010/03/28/architectural-enforcement-with-aid-of-aspectj/
Interface time:
interface IHaveA { int a {get;set;} }
interface IHaveB { int b {get;set;} }
Class A : IHaveA, IHaveB
{
public int a {get;set;}
public int b {get; set;}
}
Class B
{
IHaveA _iHaveA;
C(IHaveA iHaveA)
{
_iHaveA = iHaveA;
}
}
Class C
{
IHaveB _iHaveB;
C(IHaveB iHaveB)
{
_iHaveB = iHaveB;
}
}
Then new up B and C like this:
static Main()
{
A a = new A();
B b = new B(a);
C c = new C(a);
}
Here is a really crude idea.
Have A have a function to take an observer derived from B, and another function to take an observer derived from A.
class A
{
int a;
int b;
void getAObserver(B bInstance);
void getBObserver(C cInstance);
}
Then have A can call functions such as aWasUpdated or bWasUpdated on the instances make the member a and b sort of psuedo public to the specific classes.
A really crude way of implementing this would be
Class A {
private int a ;
private int b ;
public int getA( Object obj) throws userDefinedIllegalAccessException {
//check if obj isInstance of B
// If yes return a
// else throw userDefinedIllegalAccessException
}
public int getB( Object obj) throws userDefinedIllegalAccessException {
//check if obj isInstance of c
// If yes return b
// else throw userDefinedIllegalAccessException
}
}
class B {
public void checkAccessValue() {
try{
A objA = new A() ;
System.out.println(objA.getA(this) ;
System.out.println(objA.getB(this) ;
}
catch(userDefinedIllegalAccessException udException){
}
}
}
class C {
public void checkAccessValue() {
try{
A objA = new A() ;
System.out.println(objA.getA(this) ;
System.out.println(objA.getB(this) ;
}
catch(userDefinedIllegalAccessException udException){
}
}
}

Categories

Resources