Use of Interface for data hiding - oop

I have an interface I with two methods func A and func B and a class C with the implementation of the interface, I have two users U1 and U2.
I want the functionality so that if u1 accesses class C, func A should be called and if u2 accesses class C func B should be called.
How do i implement this using OOPs ?

I think that what you really want is:
an inteface I with just 1 method
2 classes implementing it in different way: func A and func B
Factory for that interface that take the user as parameter
Example
Let's say:
U1 is Barney, U2 is Fred.
func A is printing "I love you Betty"
func B is printing "Where's my club Wilma?!"
interface Quote is defined with a method emitQuote()
classes C and D will implement I with A and B respectively
define a factory (factory class or factory method doesn't matter) and put the User switch there.
In this way you can call:
Quote q = myFactory.getQuoteFor(u);
q.emitQuote();
This is pure OOP and I think it's pretty simple to write in a TDD fashion.

I will focus on what you've asked. Why you would want to do this and whether it's actually a good idea with respect to OO design principles is another question.
First, your requirement would look similar to the following: (note)
interface I
{
void A();
void B();
}
// class C : I { ... }
Now, let's create a User role and two implementations for user 1 and user 2:
public interface User
{
void Access(I x);
}
class User1 : User
{
public void Access(I x) { x.A(); }
}
class User2 : User
{
public void Access(I x) { x.B(); }
}
Finally, instantiate your users 1 and 2 as follows:
User u1 = new User1();
User u2 = new User2();
And "access" your C as follows:
I c = new C();
u1.Access(c); // will call c.A()
u2.Access(c); // will call c.B()
Note that this code almost completely leaves class C out of the game and instead focuses on the interface (I). If, however, you want your code to work specifically with C, simply replace I with C in the appropriate place (namely, with the parameter of method Access).
(note:) I've chosen C# for the examples, but translating to the language of your choice should be easy.

More clarification is definitely needed to determine exactly what you're trying to do, but...
Rather than having the logic in the User class, thinking OO-like, maybe a factory, like:
abstract class C : I
{
public void A() { }
public void B() { }
public abstract void CallMethod();
}
class C1 : C
{
public override void CallMethod() { A(); }
}
class C2 : C
{
public override void CallMethod() { B(); }
}
static class Factory
{
public static I GetI(User user)
{
// This is where your if blocks will go,
// and it will return either a new C1 or a new C2
}
}
This has the benefit of allowing the user to remain simple with no business code in it. The factory has to only be smart enough to know which C it wants to create based on the user. All of the actual work of calling the real method is done in the C itself.
EDIT: You may have to fiddle with the interface and the C class a little - in this case, you'd need the CallMethod() method to be in the interface. Or your factory could return a C instead of an I. Of course, without knowing the whole story, it's hard to say which is correct.

Related

Access a Kotlin Outer class using the inner object from somewhere else

I have the following setup:
class A {
fun runA() {
}
inner class B {
fun runB() { // Proxy method for runA()
runA() // its okay to call it here
}
}
}
fun test() {
val obj = A().B()
obj.runA() // how to call this one??
obj.runB() // i do not want to add a proxy method for everything in A
}
Is there any way to call runA() when I only have the B object?
Every instance of B is always coupled to an instance of A, so it should theoretically be possible (and as I am able to call runA() from within B proves that)
Best solution that I currently have is providing a accessor of A within B like so:
inner class B {
fun a(): A = this#A
fun runB() {
runA()
}
}
and then call it like obj.a().runA()
Would be nice if I could just directly call obj.runA(), I don't see a reason why it shouldn't be technically possible other than the compiler not allowing it.
Thanks for your input!
B is not A. The compiler gives B a private reference to his own A, because he needs it to execute runA. But it is private, doesn't mean that you can access from there. You can just write runA and it works inside runB because an inner class has all the members of the parent class in scope, kind of like when you use a closure. See the analogy with this example:
class A {
fun runA() {
}
fun B {
{
runA() // its okay to call it here
}
}
}
fun test() {
val obj = A().B()
obj()
}
Similarly to what you saw with the inner class, inside the closure object created when you call the member B() you can access to all variables in scope (including the instance of A that was used to invoke B()).
If you want an object B that has all the members of A you should probably have a look at inheritance instead of inner classes. Or expose an accessor to A instance like you did.

OO - Reduce boilerplate/forwarding code

Imagine the following: I have a bunch of DTO's that inherit from Foo class
class Foo { }
class FooA : Foo { }
class FooB : Foo { }
class FooX : Foo { }
Than I have one class that have encapsulated all the related logic and orchestration related with Foo data types. I provide a method DoSomethingWithData(Foo data) that do all the logic related to data provided by argument
The method implementation is something like this:
void DoSomething(Foo data)
{
if (data is FooA)
DoSomethingWithFooA((FooA) data);
if (data is FooB)
DoSomethingWithFooB((FooA)data);
if (data is FooX)
DoSomethingWithFooC((FooA)data);
}
This is a very simplified example. The advantage of this approach is:
The "Client" invoke always the DoSomething method independently of
the Foo data type
If I add a new type I only have to change the method DoSomething
What i dont like is the downcasting
The alternative is instead of exposing only DoSomething method I expose a method by each Foo data type. The advantage is that we dont have downcast but increases the boilerplate/forwarding code.
What do you prefer? Or do you have other approaches?
In this case, I would approach the problem like this (I will use Java for this example).
In your approach, for every subclass of Foo you have to provide a specific processing logic - as you have shown, and cast the Foo object to its sub-type. Moreover, for every new class that you add, you have to change the DoSomething(Foo f) method.
You can make the Foo class an interface:
public interface Foo{
public void doSomething();
}
Then have your classes implement this interface:
public class FooA iplements Foo {
public void doSomething(){
//Whatever FooA needs to do.
}
}
public class FooB implements Foo {
public void doSomething(){
//Whatever FooB needs to do.
}
}
And so on. Then, the client can call the doSomething() method:
...
Foo fooA = new FooA();
Foo fooB = new FooB();
fooA.doSomething();
fooB.doSomething();
...
This way, you don't have to cast the object at run-time and if you add more classes, you don't have to change your existing code, except the client that has to call the method of a newly added object.

superclass accesing methods of a sublass in oop

I was wondering, is it possible that a superclass to access the methods of a inherited subclass, like for example in Java?
I know that a subclass can override and even implements, in case of abstract classes, the methods of the superclass, but the question mentioned above is possible?
Thanks
Example in c#.. in superclass make abstract method, which is implemented in derived class
public abstract class SuperCLass
{
public void CallSubMethod()
{
Test(); // calls method in derived class
}
public abstract void Test();
}
public class SubClas : SuperCLass
{
public override void Test()
{
// code here
}
}
Java, PHP, Ruby, Python, C# (and so on) methods are always virtual, so, no matter what, when you override a method in a subclass, this version will be called:
public class SuperClass {
public void someMethod() {
otherMethod();
}
public void otherMethod() {
System.out.println("Super");
}
}
public class SubClass extends SuperClass {
public void otherMethod() {
System.out.println("Sub");
}
}
SubClass o1 = new SubClass();
o1.someMethod(); // Outputs: Sub
SuperClass o2 = new SubClass();
o2.someMethod(); // Also outputs: Sub
So, you not just CAN access your subclass method, you HAVE TO.
Just for comparison, in C++, for example, things work different. If you don't declare a method as virtual, you can't override it.
I' ll try to explain as they explained to me at university.
You have a reference:
Object o = new Object()
His static type(ST) is Object : this is his own type and never changes.
His dynamic type(DT) is also Object(in this case): the reference point to an object of type Object, but it can change.
for example if i write :
Object o = new String("abc") // now his ST == Object but the DT == String
That being said:
Upcasting is always permitted: consider two references s and r. the assignment s=r compile and execute always if ST(r) <= ST(s) (the static type of r is, in the hierarchi, less or equals to the static type of s)
for example:
class A { }
class B extends A { }
...
A a = new A(); B b = new B();
a = b // OK, upcast
Downcasting: at compile-time it is always legal to downcast from a type X to a type Y if X and Y belong to hierarchy.
Consider the reference s. I want to cast s to a type C, so if C <= TS(s) it will always compile if I do the cast as : C r = (C)s
for example:
class A { }
class B extends A { }
class C extends A { }
...
A a = new A(); B b = new B();
C c = new C();
...
b = c // ILLEGAL
b = (B)a // OK at compile-time but maybe at run-time it is not!
When we run our application if the downcast fails, Java raise an Exception.
Otherwise it success.
To downcast correctly:
consider a reference ref and we want to cast to a type C. So a downcast will success if DT(ref) <= C <= ST(ref) .
And the downcast will be obtained as: C ref2 = (C)ref
for example:
// I suggest to write the hierarchy in a piece of paper and
// try the rules before coding.
class A { }
class B extends A { }
class C extends A { }
class D extends B { }
...
A a = new A(); B b = new B();
C c = new C(); D d = new D();
A r = new B();
A s = new D();
a = b; // OK, upcast
a = d; // OK, upcast
/* b = c; */ // ILLEGAL
b = (B)r; // OK, downcast
d = (D)r; // downcast: it compiles, but fails at run-time
d = (D)s; // OK, downcast
/* b = s; */ // ILLEGAL
/* d = (D)c; */ // ILLEGAL
b = (B)s; // OK, downcast
b = (D)s; // OK, downcast
PS: please forgive if I made some mistake but I wrote a bit in a hurry.
In Java, It's not possible, and I think what you are asking would go against OOP.

OOP question involving the best way to reference a base class protected variable without having to typecast every-time it is used

I have a quick OOP question and would like to see how others would approach this particular situation. Here it goes:
Class A (base class) -> Class B (extends Class A)
Class C (base class) -> Class D (extends Class C)
Simple so far right? Now, Class A can receive an instance of Class C through its constructor. Likewise, Class B can receive an instance of either class C or Class D through its constructor. Here is a quick snippet of code:
Class A
{
protected var _data:C;
public function A( data:C )
{
_data = data;
}
}
Class B extends A
{
public function B( data:D )
{
super( data );
}
}
Class C
{
public var someVar:String; // Using public for example so I don't need to write an mutator or accessor
public function C() { } // empty constructor for example
}
Class D extends C
{
public var someVar2:String; // Using public for example so I don't need to write an mutator or accessor
public function D() { super(); } // empty constructor for example
}
So, let's say that I am using class B. Since _data was defined as a protected var in Class A as type C, I will need to typecast my _data variable to type D in class B every time I want to use it. I would really like to avoid this if possible. I'm sure there is a pattern for this, but don't know what it is. For now, i'm solving the problem by doing the following:
Class B extends A
{
private var _data2:D;
public function B( data:D )
{
super( data );
_data2 = data;
}
}
Now, in class B, I can use _data2 instead of typecasting _data to type D every-time I want to use it. I think there might be a cleaner solution that others have used. Thoughts?
I think B doesn't take C or D... in order for it to do what you wrote it should be
public function B( data:C )
{
super( data );
}
At least as far as I used to know :)
I doubt you can use a downwards inheritance in your case.
As for the pattern, the best one to use in situations like these is Polymorphism. Alternatively, depending on language, you can use interfaces. Or if languages allow it, even a combination of conventional code and templates.
Most modern OO languages support covariant of return type, that is: an overriding method can have a return type that is a subclass of the return type in the original (overridden) method.
Thus, the trick is to define a getter method in A that will return C, and then have B override it, such that it returns D. For this to work the variable _data is immutable: it is initialized at construction time, and from that point it does not change its value.
Class A {
private var _data:C;
public function A(data:C) {
_data = data;
}
public function getData() : C {
return _data;
}
// No function that takes a C value and assigns it to _data!
}
Class B extends A {
public function B(data:D) {
super(data);
}
public function getData() : D { // Override and change return type
return (D) super.getData(); // Downcast only once.
}
}
This how I usually write it in Java:
public class A {
private final C data;
public A(C data) { this.data = data; }
public C getData() { return data; }
}
public class B extends A {
public B(D data) { super(data); }
#Override
public D getData() { return (D) super.getData(); }
}

Is there any programming language in which you can override a method of 2 classes up?

For example, if you have class A, class B inheriting A, and class C inheriting B, is there any programming language in which class C can override a method of class A, even if class B don't override it?
class A {
method() {}
}
class B extends A{
}
class C extends B {
//override method from A
method(){}
}
AFAIK you can do this in most (if not all) OO languages, e.g. in Java and C++ for sure.
yes , It is very general case, Java does it.
This ruby code does exactly what you want:
class A
def hello
puts "hello from class A"
end
end
class B < A
end
class C < B
def hello
puts "hello from C"
end
end
B.new.hello
C.new.hello
Once executed you will have the following output:
hello from class A
hello from C
C# for one
public class A
{
virtual public int retval(int x)
{
return x;
}
}
public class B : A
{
}
public class C : B
{
public override int retval(int x)
{
return 3;
}
}
class Program
{
static void Main(string[] args)
{
A a = new C();
Console.WriteLine(a.retval(2).ToString());
}
}
I think most common languages will allow that without difficulty if all modules are recompiled. There is a gotcha in some (including C# and vb.net) if an override is added to a mid-level class which didn't have one when a child method was compiled. In that scenario, if the child classes are not recompiled, calls to their parent methods may bypass the mid-level classes (since those mid-level classes didn't have overrides when the child passes were compiled).