How to make class that can only be accessed through interface? - java

In C# or Java, how can I make a class that can only be instantiate with the Interfaces it implemented on?
Sorry if this question is asked before.
Edit: Sorry for confusing you, and this question is just asked out of curious:
For example I have:
interface iA
{
int addNum();
}
interface iB
{
int minusNum();
}
class A implements iA, iB
{
private int A;
public int addNum()
{
A += 10;
return A;
}
public int minusNum()
{
A -= 10;
return A;
}
}
class TestIface
{
public static void main(String args[]) {
A testA = new A();
iA testiA = new A();
iB testiB = new A();
testA.minusNum(); // No error, it has access to both methods
testA.addNum();
testiA.minusNum();//ERROR
testiA.addNum();
testiB.minusNum();
testiB.addNum();//ERROR
}
}
I wonder if there is a way to prevent dev from just make testA and access both methods.

How about making the constructor private?
class A implements iA
{
public int returnNum()
{
return 10;
}
private A(){}
public static iA getInstance(){
return new A();
}
}

You can make the constructor private and define a static Create method that creates new instances.
public interface ITest
{
}
public class A : ITest
{
private A()
{
}
public static ITest Create()
{
return new A();
}
}
Then the only way to create an instance of your class (besides reflection, but that's another story!) is to call the Create method like this:
ITest test = A.Create();

You cannot instantiate something via an interface. You can only declare it as an interface. If your goal is to make addNum only accessible via iA and minusNum only accessible via iB, you can try explicit interface implementation (although it has its own drawbacks):
class A : iA, iB
{
private int A;
int iA.addNum()
{
A += 10;
return A;
}
int iB.minusNum()
{
A -= 10;
return A;
}
}
This will at least give you the compile time effect you are looking for:
class TestIface
{
public static void main(String args[]) {
A testA = new A();
testA.minusNum(); // does not compile
testA.addNum(); // does not compile
iA testiA = new A ();
testiA.minusNum();//does not compile
testiA.addNum();
iB testiB = new A ();
testiB.minusNum();
testiB.addNum();//does not compile
}
}
However, this does not mean addNum is only accessible via a variable which is declared as iA. To illustrate, you can do:
A testObj = new A ();
(testObj as iA).addNum (); // this will compile
You can even do:
iB testObj = new A ();
(testObj as iA).addNum (); // this will also compile, and execute fine
If you want to further prevent the explicit casting from and to the concrete class, you need have to take the advice others have offered: make your concrete class a nested private class and introduce a factory to produce the instance:
class Factory
{
private class A : iA, iB
{
int iA.addNum () {...}
int iB.minusNum () {...}
}
public iA GetInstanceOfiA ()
{
return new A ();
}
public iB GetInstanceOfiB ()
{
return new A ();
}
}
This still does not prevent the casting from iA to iB, which I guess you have to create two separate concrete classes to cater.

Related

In Java how to refer subclass variable without declaring that variable in parent class?

public class MyTest {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
class A {
private final int x = 5;
protected int getX() {
return x;
}
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
In this example, I need to print subclass value in the parent class.
It is working fine. No issue.
Now it is printing 10.
But I do not want to define that property in the parent class A.
Because in this example this x datatype is very simple. So no issue.
But in real-time I want to use other datatype which may be another Class variable or List<something> which have huge data.
So ultimately I do not wish to store that value in Class A.
Because it is redundant data. It will slow down in my Hibernate thing.
Please let me know, how to achieve this without declaring variable in parent class. But I still need to use subclass variable in parent class.
make abstract your class A and the getX(); method.
public class Test {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
abstract class A {
protected abstract int getX();
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
and override the toString method in place of your print method
#Override
public String toString() {
return String.valueOf(getX());
}
the final code
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
abstract class A {
protected abstract int getX();
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
protected int getX() {
return X;
}
}
you could also define as static your x variable
But as say Andrew Tobilko you can consider also to use an interface if A doesn't represent a stateful entity.
It's certainly the best solution for your case, mix the use of an interface and an abstract class
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
interface MyInterface {
int getX();
}
abstract class A implements MyInterface{
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
public int getX() {
return X;
}
}
You need the getX within the parent class, but you don't have information enough to implement this method there.
You can declare this class as abstract and mark the method with abstract as well. Doing that, you are handing the responsibility of method implementation over its subclasses and preventing from parent field declaration.
If the A doesn't describe any state (only actions/methods), you should consider replacing it with an interface. At the current state, it is the case.
You could make the parent class abstract, eliminate the property in the parent class, make getX() abstract, and then leave print() as concrete. Then just use the concrete implementation of getX() in the child class.

Java mutual dependency with interfaces set in constructor

I have 2 classes that rely on each other and they both have their respective interfaces. However, I cannot setup the constructor on both classes cleanly. In short, one class needs to be instantiated before the other class gets instantiated.
Class A implements IA {
public A(IB b) {
myBclass = b;
}
private IB myBclass;
}
Class B implements IB {
public B(IA a) {
myAclass = a;
}
private IA myAclass;
}
static void main(String[] args) {
A a = new A(null);
B b = new B(a);
a.setB(b); // how can I avoid doing this
}
I would like to avoid setting member variables outside the constructor.
You can have one construct the other.
class A implements IA {
private IB myBclass;
public A() {
myBclass = new B(this);
}
// etc.
}
class B implements IB {
private IA myAclass;
public B(IA a){
myAclass = a;
}
// etc.
}
That way you don't have to alter them after construction.
public static void main(String[] args){
A a = new A();
B b = a.getB();
}

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){
}
}
}

Inheritance in Java

Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}

Two questions on inner classes in Java (class A { class B { } })

Sorry for the bad title, but I couldn't think of a better one.
I'm having a class A and a class B which is kind of a sub class of A, like so:
(Is there actually a correct name for it? Isn't "sub class" reserved for inheritance?)
class A {
int i = 0;
class B {
int j = 1;
}
}
class Test {
public static void main() {
A a = new A();
B b = a.new B();
A c = ??? b ??? // get "a" back
}
}
From B every property of A can be accessed, therefore both, a.i and b.i, return 0. Now, I'm wondering whether it's somehow possible to retrieve the original object of type A out of b, as b contains everything that a contains? Simple casting apparently doesn't do the trick.
Second one:
class A {
void print() {
System.out.println("This is class A.");
}
class B {
void print() {
// <--- How to access print() of class A (like this.A.print() or smth)?
System.out.println("This is class B.");
}
}
}
You could alternatively also provide me with some good resources on this topic, as I've been too stupid to find a good one so far.
Thanks in advance. :)
There doesn't seem to be a way to access the outer class from outside. But you can do it like this:
class A {
int i = 0;
class B {
final A outer = A.this;
int j = 1;
}
}
class Test {
public static void main() {
A a = new A();
A.B b = a.new B();
A c = b.outer // get "a" back
}
}
ClassName.this will be the instance of the outerclass associated with the instance of an inner class.
You can access it with the ParentClass.this syntax from within the inner class.
e.g.
public class Outter
{
class Inner {
public Outter getOutter()
{
return Outter.this;
}
}
public Inner getInner(){
return new Inner();
}
}
class Runner{
public static void main(String[] args){
Outter out = new Outter();
Outter.Inner inner = out.getInner();
System.out.println(inner.getOutter().toString());
}
}
[Edit: My answer is appropriate for C# programmers, but I can't guarantee that its applicable to Java.]
B is an inner class, not a subclass of A. Additionally, B does not hold an instance of A, so your code as is cannot return any instance of A.
You need to restructure your classes as follows:
class A
{
public class B
{
public A Parent;
public B(A parent)
{
this.Parent = parent;
}
}
}
Now your B class has a field 'Parent' which returns its parent. You can use these classes as follows (this is C# syntax, because I don't know if Java has a different syntax for instantiating inner classes):
public static void Main(String[] args)
{
A parent = new A();
A.B child = new A.B(child);
A backToParent = child.Parent;
}
Of course, creating your B class in this way seems little funny: technically, you can pass in any parent. It would probably be better to rewrite your A class with a method which returns a B:
class A
{
public class B
{
public A Parent;
public B(A parent)
{
this.Parent = parent;
}
}
public B getChild()
{
return new B(this);
}
}
public static void Main(String[] args)
{
A parent = new A();
A.B child = A.getChild();
A backToParent = child.Parent;
}
this seemed to work for me
class A {
int i = 0;
class B {
int j = 1;
}
}
class Test {
public static void main() {
A a = new A();
A.B b = a.new B();
A c = (A)b.getClass().getDeclaredField("this$0").get(b);
}
}

Categories

Resources