Is inheritance possible without Encapsulation in java?
Is this possible?
Yes, it is possible. Inheritance and Encapsulation do not depend on each other, but when used both, they provide more flexible and powerful application structures.
For instance, below, there is inheritance without encapsulation. Note - that it is a bad approach, and do not use this approach in your projects. It is just for the demonstration purposes.
class A {
public int a;
public int b;
public String c;
public A() {
}
protected void someMethod() {
}
}
class B extends A {
// a, b, c from the parent A class are accessible here
public int d;
public String e;
public B() {
super();
}
// someMethod() is accessible here
}
In the code above, there is no encapsulation implemented, all class fields are public, and can be changed from outside.
But this approach prevents you from changing the structure of your classes withour affecting the rest of your code.
And it is strongly recommended to combined use of inheritance and encapsulation in your applications.
Hide your class structure and implementations over this structure. And show (make public) only methods to operate with the class instance internals from the outside.
Related
I'm trying to implement something to this effect:
Base class A has a method getFileName()
Two derived classes B and C have overridden implementations of that method, returning file names specific to B and C.
Class A needs to use the services of a singleton class S
The reason I want it to be a singleton is because (a) I want a guarantee that it will only be constructed once and (b) I want eager initialization of that class, which happens at app startup, and not at first use.
Class S needs to do its work work based on the file name (E.g., read in the contents of that file) - which depends on which of A's subclasses is used.
This seems to present an unavoidable conundrum, because:
most implementations of Singleton are static based (pure static class; or ENUM with a static parameter passing)
static classes/methods/blocks cannot call non-static methods...
... and making getFileName() static will make sure that it cannot use inheritance overrides!
How can I implement this design? (I'm open to changing the design if a better pattern is available)
... needs to use the services of a singleton ... which depends on which of A's subclasses is used:
That means the Singleton is not really your problem, it is the acquisition of the correct class based on the type asking!
Your design is too tightly coupled the way you are trying to do it. You need to completely decouple the Service from the Consumers of the service, Singleton is not important in this exercise.
What you need is some form of dependency injection.
This is exactly the type of problem that Guice was created to solve by being able to provide what classes get injected based on another classes type in a binding. That said ...
Most people do not realize that Java has always supported DI via the Constructor. Guice makes this less hard coded, but it is still a dependency that is injected to an instance.
Guice would make this trivial by injecting the correct service based on the class type. But it can be done without any DI framework/library. If using Guice is considered to heavy handed for your case then it can still be done easily.
Below is one way to do it without a framework/library:
public class Solution
{
static class Singleton
{
public static final Singleton INSTANCE;
static { INSTANCE = new Singleton(); }
private Singleton() { /* this is important */ }
public void doWhatever(#Nonnull final B b) { /* whatever */ }
public void doWhatever(#Nonnull final C c) { /* whatever */ }
}
static abstract class A
{
private final Singleton s;
public A(final Singleton s) { this.s = s; }
public abstract String getFilename();
}
static class B extends A
{
public B(final Singleton s) { super(s); }
#Override
public String getFilename() { /* code goes here */ }
}
static class C extends A
{
public C(final Singleton s) { super(s); }
#Override
public String getFilename() { /* code goes here */ }
}
}
The singleton anti-patterns you mention are just that:
The Singleton pattern should by hidden behind a Factory pattern. Your consumers of what needs to have 1 and only 1 should not care if there is 1 and only 1. They should only care that that object conforms to some contract of some interface.
My implementation is a naive Factory to create in static block. Most are create on first use which is not any better.
Using Enum to create Singleton objects is a misuse of the semantics of Enum and an anti-pattern and impossible to properly unit test.
Same with the all static utility class approach, impossible to unit test or replace with a different implementation. A combination of the two is a complete abomination that is impossible to unit test and a complete nightmare to maintain!
How you determine which subclass of A the Singleton works on is easy:
That is what overloading is for as shown in the code above.
Anything else is not doing it right. instanceof fail, reflection bigger fail.
Selecting logic based on Type can be done with overloading methods, or generics or with the appropriate design pattern.
Strategy Pattern would account for that easily and make N number of subclasses manageable and extensible at runtime.
I think you need to decide if S uses A or if A uses S.
If S uses A, then A could be a base class or interface, and S would have a method that accepts instances of A, which are overridden with the correct implementation of getfileName().
If A uses S, then A should be abstract with respect to getFileName() forcing an implementation to be constructed, and it should internally call it's yet-to-be-defined getFileName() passing that as an argument to S.
Singletons are the glue between Object-Oriented solutions and non-Object-Oriented solutions, so you avoid the conundrum by
Having your objects passed to the non-object oriented singleton "utility routine"
Having the resolved parameters passed to the non-object oriented singleton "utility routine"
Example code for the first technique
// this could be abstract class too, as long as getName() is abstract
public interface Nameable
public String getName();
}
public enum Utility {
INSTANCE;
public static deleteByName(Nameable nameable) {
createBackup(nameable.getName());
updateIntentLog(nameable.getName());
removeFile(nameable.getName());
updateAuditLog(nameable.getName());
}
}
or
public abstract class Nameable {
public abstract String getName();
public void delete() {
Utility.INSTANCE.deleteFile(getName());
}
}
public enum Utility {
INSTANCE;
public void deleteFile(String name) {
...
}
}
You can make singleton classes that you initialize manually, i.e. have a static instance variable but also a static initialize() method. The initialize throws if you try to initialize twice. This allows you to choose at run-time which subclass to use and also it makes the initialization order clear.
I have a series of classes, A,B,C... (several dozen in total) that share common code. There can be many instance of each class A,B,C... . I'm planning to create a superclass, Abstract, that will contain that code instead.
Problem is, the common stuff works on an object that is unique on a per-class (not per-instance) basis. This is currently solved by A,B,C... each having a static field with the corresponding value. Obviously, when I refactor the functionality into Abstract, this needs to be changed into something else.
In practice, it currently looks like this (note that the actual type is not String, this is just for demonstrative purposes) :
public class A implements CommonInterface {
private static final String specificVar = "A";
#Override
public void common() {
specificVar.contains('');
}
}
public class B implements CommonInterface {
private static final String specificVar = "B";
#Override
public void common() {
specificVar.contains('');
}
}
The best idea I've come up with until now is to have a Map<Class<? extends Abstract>,K> (where K is the relevant type) static field in Abstract, and A,B,C... each containing a static initalization block that places the relevant value into the map. However, I'm not convinced this is the best that can be done.
Note that I'm not using any DI framework.
So, what would be the most concise, in terms of code contained in the subclasses, way to refactor the static fields in A,B,C... handled by the common code, without sacrificing field access efficiency?
Perhaps an enum is what you want.
enum MyInstances implements MyInterface {
A {
fields and methods for A
}, B {
fields and methods for B
};
common fields for all MyInstances
common methods for all MyInstances
}
// To lookup an instance
MyInstances mi = MyInstances.valueOf("A");
As you haven't shown any source code, we can't really tell if the use of static fields is a good or a bad design choice.
Considering the use of static fields by the subclasses is indeed a good design choice, the first way of having common code in a superclass to access them is by calling abstract methods that would be implemented in the subclasses.
Example:
public abstract class SuperClass {
public void processCommonLogic() {
// Common logic
// Execute specific logic in subclasses
processSpecificLogic();
}
public abstract void processCommonLogic();
}
public class ASubClass extends SuperClass {
public static int SPECIFIC_SUBCLASS_CONSTANT = 0;
public void processSpecificLogic() {
// Specific subclass logic
doSomethingWith(ASubClass.SPECIFIC_SUBCLASS_CONSTANT);
}
}
You could use the Template Method Pattern.
Have an abstract method getValue() defined in your abstract class and used within your abstract class wherever you require the value. Then each of your subclasses simply need to implement the getValue method and return the correct value for that subclass.
We can access the Super Class methods which consists of operations on private data members and print the results.But why can't I print the private data members of Super Class with the SubClass object calling them in my main function? Someone please explain me.
Here is the example below.
class SuperClass1
{
private int a;
private int b;
SuperClass1(int p,int q)
{
a=p;
b=q;
}
SuperClass1(SuperClass1 obj)
{
a=obj.a;
b=obj.b;
}
SuperClass1()
{
a=-1;
b=-1;
}
int Vol()
{
return a*b;
}
}
class SubClass1 extends SuperClass1
{
int c;
SubClass1(int p,int q,int r)
{
super(p,q);
c=r;
}
SubClass1(SubClass1 obj)
{
super(obj);
c=obj.c;
}
SubClass1()
{
super();
c=-1;
}
}
public class Super
{
public static void main(String[] args)
{
SubClass1 obj1=new SubClass1();
//System.out.println("The values of obj1 are:"+obj1.a+""+obj1.b+""+obj1.c);
int vol=obj1.Vol();
System.out.println("The volume is :"+vol);
}
}
security and encapsulation
The superclass is letting its subclasses use only the public and protected methods/fields.
This allows the designer of the superclass to change the implementation of these methods if he sees it better, without breaking the subclass's correctness.
A text book example is a complex number class.
The programmer using this class only needs its functionality, he doesn't care if the implementation is with imaginary and real fields or with radius and theta fields [two distinct ways to represent complex number].
It allows the designer of the ComplexNumber class more freedom if he wants to change the class in later versions, and it also allows the user less worries: he doesn't need to take care for all the details, some are being taken care of for him.
Bonus: note you can break this behavior and access private fields and methods by using reflection - but when you do so - all bets are off, and you do it on your own responsibility.
Your question isn't very clear without an example, but I suspect that the "methods which consist of operations on private data members" aren't private. It doesn't matter that they work by accessing private data - they're not private themselves. It would be pretty pointless having access modifiers if public methods could only access other public members etc.
The whole point of encapsulation is that only the class itself should care about implementation details such as the fields in question, but can expose a contract in terms of its public (and protected) API. Code outside the class shouldn't care about the private implementation details.
JLS says:
Members of a class that are declared private are not inherited by
subclasses of that class. Only members of a class that are declared
protected or public are inherited by subclasses declared in a package
other than the one in which the class is declared.
So, to answer you question. No, private members are not accessible by subclasses.
Private members are not inherited; only the protected and public members are.
If possible, you can do one of the following:
Make the private properties of the superclass protected
Make public getters (and setters if needed) for the private properties
I have a base class that captures some functionality common to two classes. In other words, I can create one base class and make these two classes subclasses of that base class. However, for each of these sub classes, the number of instances can be created is 1 (i.e. each sub class has to be a singleton).
I googled and found that there's a reasonable debate going on over this. Although there are several solutions available, I am not sure whether they would fit in my case.
can anyone tell me how I should design this?
You can make each class separately a singleton, and make the base class abstract. Not sure what's the debate -- just that singletons, in general, aren't a great idea?
Use the Abstract factory pattern. Have a separate class with methods to retrieve the singletons, and let it hold the references to the singletons in instance variables or in a map.
You may not want the increased complexity, but frameworks like Spring were created to solve these kind of issues (among others).
It seems that Pico Container is alive and well, and it may be the simplest while still solid solution. Look at the inversion of control topics, and let the framework inject the singletons where you need them.
In short, don't try to make the singletons manage access to themselves. Delegate that on something else.
There's nothing inherently wrong in having singleton classes with complex inheritance. In fact, class hierarchies with private constructors (no instances) are very useful in many situations. You just have to decide how you want to manage the two important aspects of singletons: creation, and access.
I don't know if you need an example but I gave it a try. Without knowing any of your details this example is very vague. I am also here to learn so let us know what you end up implementing.
The Base class:
public abstract class BaseClass {
public void someMethod() {
System.out.println("base class hello: " + this);
}
public abstract void someOtherMethod(String value);
}
One of the subclasses:
public class SubClassOne extends BaseClass {
private static SubClassOne instance;
private SubClassOne() {}
public static SubClassOne getInstance() {
if (instance == null) {
instance = new SubClassOne();
}
return instance;
}
public void someOtherMethod(String value) {
someMethod();
System.out.println("sub class hello: " + value + " " + this);
}
public static void main(String[] args) {
SubClassOne one = SubClassOne.getInstance();
SubClassOne two = SubClassOne.getInstance();
SubClassOne three = SubClassOne.getInstance();
SubClassOne four = SubClassOne.getInstance();
one.someOtherMethod("one");
two.someOtherMethod("two");
three.someOtherMethod("three");
four.someOtherMethod("four");
}
}
I had a similar requirement: I had multiple cache maps with repeating methods and members, so I've created an abstract class like:
public abstract class AbstractCache<T> {
protected final Map<String, T> cache;
protected AbstractCache() {
this.cache = getDefaultExpiringMap(TimeUnit.HOURS.toMillis(4));
}
public Map<String, T> getCache() {
return cache;
}
public T getAll(String id) {
return cache.get(id);
}
}
Then I've extended this class and created a singleton instance:
public final class FooCache extends AbstractCache<Set<Integer>> {
public static final FooCache INSTANCE = new FooCache();
private FooCache() {
super();
}
public void add(String fooId, Integer value) {
cache.computeIfAbsent(fooId, k -> new HashSet<>()).add(value);
}
}
And the usage:
public static void main(String[] args) {
FooCache.INSTANCE.add("a", 1);
System.out.println(FooCache.INSTANCE.getAll("a"));
}
I'm not an expert in Java, so I don't know if this is technically legal Java code (perhaps another poster can comment):
Make the base classes inherit from a generic class Singleton.
Example:
class Singleton<T> {
protected Singleton(); //constructor
private static T _instance;
}
class DerivedOne extends Singleton<DerivedOne>{
protected DerivedOne(){} //constructor
}
class DerivedTwo extends Singleton<DerivedTwo>{
protected DerivedTwo(){} //constructor
}
Inheritance is not the only way to re-use common functionality. Containment may be preferable in the general case.
Consider the following solution in which class A and B are the singletons, and the common functionality is in class AB, but instead of extending AB, both A and B use an instance of AB which is a singleton itself.
class AB { //common functionality of A and B
//singleton pattern here
//common data and functionality here
}
class A {
private AB ab = AB.getInstance();
//singleton pattern here
//unique functionality and data of A
//to use any of the functionality in AB delegate to member ab
}
class B is similar to A.
in this solution there is a single instance of every data and functionality of both A and B (and AB)
Note that if clients of A and B need to access the common public methods in AB, then
AB, A and B should implement an interface of those public methods, and A and B implementation should delegate the call to ab.
The solution proposed by Ernest below, may be a shortcut in some situations, but in general is a wrong solution.
To explain why Ernest's solution may be wrong, let's describe that solution in a different way.
Suppose i have a singleton class A and i discover that i need to write another singleton class B, but i need some of the functionality of A in B. So i factor out the common data and functionality of A into an abstract class AB and make both A and B extend AB.
The reason why it's wrong, in general, is because this solution takes a subset of the data and functionality which is supposed to exist only once, and places it in a sub-class (AB), effectively and potentially duplicating it in every sub-class that will be created. Now, after getting an instance of A and an instance of B, you have two instances of the subset data and functionality in AB.
If for example, the common functionality placed in the base class writes some initial data to the file named "myData", then both of your singletons will execute this code even though it was only meant to be executed once, and when the later executes it it will wipe out the file created by the former.
Therefore, in general, the solution described here does not use inheritance, and ensures that a singleton encapsulates the common functionality as well as the singleton classes that use it.
Why do we need constructors and private members in the abstract class? It is not like we are ever going to create an instance of that class.
You will create instances, just instances of a derived class. Those derived classes will still need to call constructors, and can still call members of the abstract class - which may in turn use private members.
Here's an example (not a terribly useful one, but just to show the basic idea...)
public abstract class NamedObject
{
private final String name = name;
protected NamedObject(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
public class Computer extends NamedObject
{
private final int processorSpeed;
public Computer(String name, int processorSpeed)
{
super(name); // See, the constructor is useful
this.processorSpeed = processorSpeed;
}
public String toString()
{
return getName() + " (" + processorSpeed + ")";
}
}
I can't say I write abstract classes that often, generally preferring composition to inheritance, but when I do create them I certainly use constructors and private members.
Abstract classes provide a partial implementation of some interface. It's perfectly reasonable to consider that you might want to provide part of that implementation and disallow client code (concrete subclasses) from accessing the specifics - i.e. an extension of the principle of encapsulation.
Marking some members as private forces the inheriting class to call protected methods to access that partial implementation; providing a constructor allows for subclasses to initialise the parent's encapsulated state during their own construction.
Unlike an interface, an abstract class that defines data fields is in fact instantiated in the sense that these data fields are allocated. It is just that they are never instantiated on their own, they are instantiated as part of something bigger - the subclass. So when the subclass is built, the supertype is built as well, which is why you would need a constructor.
Depending on your hierarchy, your abstract class may have a meaning and state. For example, if your application is a school you may have the notion of a person (that has a name and an SSN), but you would have different subtypes for students and for faculty. Because both types of people share certain state structure (name and SSN) you would have both classes extend the Person class. But you would never simply instantiate a person directly.
In addition to Jon's answer, I'd like to mention that abstract classes still go well with composition, if you keep the subclass tree shallow. I.e. it is great for providing a common base class for a few closely related objects, but not for creating a gigantic tree of subclasses.
Why do you need private class? I think that you are confusing abstract classes with interfaces. Unlike interfaces, abstract classes can hold functionality. For example:
public class AbstractBase{
private int num;
public AbstractBase(int number){
this->num = number;
}
public int method(){
return ( this->num * this->templateMethod());
}
public abstract int templateMethod();
}
public class ConcreteDerived extends AbstractBase{
public ConcreteDerived(){
super(4);
}
public int templateMethod(){
return number; //number is the result of some calculation
}
}
In this example, you´ll never explicitly instantiate AbstractBase, but by declaring members and constructors, you can customize the functionality of your classes (this is called template method).
Assuming you're doing ad hoc code or prototyping, you do instantiate abstract classes (or maybe even interfaces) from time to time. They're called anonymous inner classes (one, two) and look like this:
// you have this...
public abstract class SomeClass {
public abstract String returnAString();
}
// ...and this...
public class OtherClass {
public void operate(SomeClass c) {
System.out.println(c.returnAString());
}
}
// ...so you do this:
OtherClass oc = new OtherClass();
// this is one of the reasons why you need to specify a constructor
oc.operate(new SomeClass() {
#Override
public String returnAString() {
return "I'm an anonymous inner class!";
}
});
This example is of course quite redundant but should expose the point. Some existing frameworks even rely on the heavy usage of this behaviour, namely Apache Wicket at least.