Access levels of classes in java [duplicate] - java

This question already has answers here:
What is the difference between public, protected, package-private and private in Java?
(30 answers)
Closed 5 years ago.
A class from a subpackage needs to access a class from a package one level up. So, I need to keep the target class as public. But I don't want that class to be accessed by any other class. What can I do?

You don't have dozen solutions.
Java is not C++ or OOP languages that have the concept of "friend class".
The protected modifier provides a privileged access for the subclasses but you will not subclass a dependency to access it.
It really makes no sense.
So if you can refactor : move the user class in the same package as the used class and use the private package modifier.
Otherwise, make the class a private nested class of a public factory class that will return a instance of a specific interface matching to the class API you want to protect the access.
In this way, the client classes will only communicate with the interface API.
Of course any class will still to be able to retrieve the instance but will never be coupled with an implementation class.
So in a some way, it protects the access to the class.
FooAPI :
public interface FooAPI {
void foo();
//....
}
FooFactory :
public class FooFactory{
private MyFactory(){
}
private class MyPrivateFoo implements FooAPI{
// implements the interface methods
#Overrided
public void foo(){
// ....
}
}
public FooAPI of(){
return new MyPrivateFoo();
}
}
Edit for your comment :
The used class has public methods which change its state. Only
specific classes are allowed to change its state, others are not. How
can this be solved ?
The question was not very clear about class access meaning.
With this comment, it is clear.
State changing is a functional behavior.
You want to protect the state change of an instance of a specific class ?
So make this class responsible to decide whether the state should change or not.
Don't provide public methods that allow to do it directly.
You have to change your design.
For example introduce a public doProcessing() method in the class with the state you want to control and make this method responsible to change the state instance if relevant.
You can be interested in Domain Model design that gives a natural and straight way to address this kind of issue.
And to ensure the validity of a behavior, you have a powerful tool : the unit and integration tests.
So use them.

Use protected modifier so the subclass and the package level classes can alone access it
PLease refer to the link for details on access levels
https://www.programcreek.com/2011/11/java-access-level-public-protected-private/

Refactor your code, depending on your concrete scenario:
Make the class in the subpackage inherit from the class a level up.
Create an interface in the subpackage that provides the methods you want to access and let the class in the package implement it.
Move one of the classes.

A class can not be private or protected. The only access modifiers of class is public or no-modifier. But you can use public, private, protected or no-modifier as inner class.
A class can access all properties of another class in same package except private modifier.
Keep all properties as protected in parent class. So, only child class from same or other package can access the parent class properties. Other class will not be able to access.

Related

Child Class cannot be protected

import java.util.*;
public class NewTreeSet2{
void count(){
for (int x=0; x<7; x++,x++){
System.out.print(" " + x);
}
}
}
protected class NewTreeSet extends NewTreeSet2{
public static void main(String [] args){
NewTreeSet2 t = new NewTreeSet2();
t.count();
}
}
Here, I cannot make the NewTreeSet sub class as protected. Why is this? I am not trying to accomplish anything, this is only for my understanding of the access specifiers.
public is the only access-modifier that can explicitly be applied to a top level class in Java. The protected modifier in case of a class can only be applied to inner classes.
Section 8.1.1 of the Java language specification says this :
The access modifiers protected and private pertain only to member classes within a directly enclosing class declaration
So why can't top level classes be marked as protected? The purpose of protected access modifier in Java is to add restrictions on the access to a member of a class. Since a top level class is not a member of any class, the protected access modifier does not make sense for top level classes. Inner classes can be marked as protected because they are indeed members of a class. The same rules apply for private as well.
A class definition itself can only be public or package-private. Public classes must be defined in their own file and the filename must be the class name.
The documentation doesn't say anything about why there are only two access modifiers for the top level, but one might say that it is logical:
The protected access modifier makes sure only instances of the same or a child class can access the subject. Polymorphism is not applicable to classes, only to instances of classes. Thus the protected keyword there doesn't make sense.
If you want to protect the construction of objects, you should specify an access modifier to your constructor.
"Why can't we have the 'protected' modifier for a top-level class".
Assume it's allowed to use protected modifier for a class. Then what will happen, it will be visible to all the classes in the same package which is the same behavior what a default (package-level) access class will possess. Additionally this 'protected' class should be visible to all the subclasses outside package also. But unfortunately you would not be able to create any subclass of this class outside the package because this class itself will not be visible outside the package. Hence without the subclass specific behavior, this 'protected' class will be exactly same as a package-level or default access class. So, there is absolutely no need of 'protected' modifier for classes and hence, not permissible as well.
---This was posted in a different forum, by B Verma, found this answer according to which all of you said. It was really helpful, thank you.
http://www.coderanch.com/t/585021/java/java/Protected-access-modifier-class-level

How is abstract class different from concrete class?

I understand WHY we need Abstract Class in Java - to create sub-classes. But the same can be achieved by concrete class. e.g. Class Child extends Parent. Here Parent can very well be abstract & concrete. So why do we have ABSTRACT??
Abstract classes cannot be instantiated directly. Declaring a class as abstract means that you do not want it to be instantiated and that the class can only be inherited. You are imposing a rule in your code.
If you extend your Parent/Child relationship example further to include a Person class then it would make good sense for Person to be abstract. Parent is a concrete idea and so is child. Person is an abstract concept in reality as well as in code.
One benefit is that you explicitly define and protect the idea of the abstract class. When you declare a class as an abstract there's no way that you or anyone else using your code uses it incorrectly by instantiating it. This reasoning is similar to why we specify functions and fields as public, private or protected. If you declare a function or member as private you are in effect protecting it from improper access from client code. Privates are meant to be used within the class and that's it. Abstract classes are meant to be inherited and that's that.
Now, do you have to use abstract classes and define functions and fields as private instead of public? No, you don't. But these concepts are provided to help keep code clean and well-organized. The abstract class is implemented in all object-oriented languages to my knowledge. If you look around you will see that C++, C#, VB.NET etc. all use this concept.
A better, specific example:
In the example above the Shape class should be abstract because it is not useful on its own.
Abstract class means it is abstract not complete. It needs another class to complete it and/or its functionalities. You need to extend the abstract class. It will be useful with Certain class eg. Fruit all fruits have the same property like color. But you can have different properties for different fruits like is it pulpy such as orange or not eg Banana etc.
I know this is an old question but it looks like the poster still had some questions about the benefit of using an abstract class.
If you're the only one who will ever use your code then there really is no benefit. However, if you're writing code for others to use there is a benefit. Let's say for example you've written a caching framework but want to allow clients to create their own caching implementation classes. You also want to keep track of some metrics, like how many caches are open, hypothetically. Your abstract class might look something like this:
public abstract class AbstractCache {
public final void open() {
... // Do something here to log your metrics
openImpl();
}
protected abstract void openImpl() { }
}
On its own the AbstractCache class is useless and you don't want clients to try to instantiate one and use it as a cache, which they would be able to do if the class was concrete. You also want to make sure they can't bypass your metric logging, which they would be able to do if you just provided them a Cache interface.
The point of abstraction is not to create sub-classes. It's more about creating Seams in your code. You want code to be test-able and decoupled which lead to the ultimate goal of maintainability. For similar reasons, abstraction also buys us the ability to replace a bit of code without rippling side effects.
An abstract class is meant to be used as the base class from which other classes are derived. The derived class is expected to provide implementations for the methods that are not implemented in the base class. A derived class that implements all the missing functionality is called a concrete class
According to my understanding
Abstract Class is a class which just describes the behavior but doesn’t implement it.
Consider this Java example for Abstract Class:
public interface DoSomething(){
public void turnOnTheLight();
}
Concrete Classes are those, which are to be implemented.
For Example:
public abstract class A(){
public void doIt();
}
public class B extends A(){
public void doIt(){
//concrete method
System.out.println(“I am a Concrete Class Test”);
}
}
In other words, A concrete class in java is any such class which has implementation of all of its inherited members either from interface or abstract class.
For those who seek only differences in pure technical approach, the clearest difference between concrete parent classes and abstract parent classes is the obligation for children to include/implement specific methods.
A concrete parent class cannot force/oblige its children to include/implement a method. An abstract parent class oblige its children to do that by declaring abstract methods.
Apart from the above, it comes to design and functional requirements to dictate the use of abstract class. Such examples can be found on javax.servlet.http.HttpServlet class

Why should we declare interface methods as public? [duplicate]

This question already has answers here:
Protected in Interfaces
(15 answers)
Closed 5 years ago.
When I implement an interface method, I am forced to make it a public method.
We may have cases where we want to use either the default (like in case of access within the same package) or protected.
Can anyone please explain the reason behind this limitation?
Interfaces are meant to define the public API of a type - and only that, not its implementation. So any method (or static member) you define in an interface is by definition public.
Since an interface can't contain any concrete implementation, there is no way to call any member methods from within. And declaring such methods but leaving the calls to them to subclasses or totally unrelated clients would mean your type definition is incomplete and brittle. That is why if you need to define protected or package access members, you can do so in an abstract class (which may also contain implementation).
Maybe this will provide some answers.
To my knowledge, you use interfaces to allow people from outside your code to interact with your code. To do this, you need to define your methods public.
If you would like to force someone to override a given set of private methods, you might want to declare an abstract class with a series of abstract protected methods.
An interface is a contract that the class that implements it will have the methods in the interface. The interface is used to show the rest of the program that this class has the methods and that they could be called
EDIT: This answer is meant for C# interface implementations. In this case of Java the scenario is similar just that the syntactic analyzer wants a public keyword mentioned in the interface, which is implicitly done in C#
Interface methods are implicitly public in C# because an interface is a contract meant to be used by other classes. In addition, you must declare these methods to be public, and not static, when you implement the interface.
interface IStorable
{
void Read( );
void Write(object obj);
}
Notice that the IStorable method declarations for Read( ) and Write( ) do not include access modifiers (public, protected ..). In fact, providing an access modifier generates a compile error.
class Document : IStorable
{
public void Read( )
{
//
}
public void Write(object obj)
{
//
}
}
Just think about interfaces as Contracts to be implemented as public
If we mark a interface method as private the implementing class wont
see the method and cant override it.
If we mark a interface method as protected the implementing class
wont see the method unless it is in the same package as the
interface.
If we mark a interface method without any access modifier the
implementing class wont see the method unless it is in the same
package as the interface

Defining inner class outside java file

I want to create a class, ClassB, as inner class of ClassA, but I want to write down outside ClassA.java file.
How can I do this?
It will be a lot of inner class, and ClassA.java file will be enormous.
UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
Thanks.
The simple answer, is no you cannot.
By virtue of being an inner class, the class has to be inside the scope of the parent class.
If your class is really going to be enormous, it probably says something about the design of your class. Are you making proper use of encapsulation?
Put all your classes in a package and define the classes to be package private.
package com.example.here
class Hello{
//...
}
Notice the absence of the keyword public? You will only be able to create an instance of the class Hello if the class creating it is in the com.example.here package.
Try the following ...
Hand over a reference of the outer-class to the no-longer-inner-class
Use packages and make the no-longer-inner-class package-private (Jeremy's answer)
In the very rarest of cases, it might actually be best to go with inner classes, and at the same time have them do work elsewhere. If this really is you, please read on ...
How to keep inner classes small
a) Extend from outer classes
class Outer {
class SomeInnerClass extends SomeClass {
// More specific code here
}
}
class SomeClass {
// A lot of generic code here (in a different file)
}
b) Use abstract methods
One of the (more correct) reasons for using inner classes, usually has to do with the use of the exact instance of the outer-class. To tackle it in a generic fashion in the base class, use abstract getters.
abstract class SomeClass {
protected abstract SpecificData getSpecificData();
void someMethod() {
SpecificData specificData = getSpecificData();
// Do work with the "specific data" here ...
}
}
class Outer {
private SpecificData mSpecificData = new SpecificData();
class SomeInnerClass extends SomeClass {
#Override
protected SpecificData getSpecificData() {
return OuterClass.mSpecificData;
}
}
}
I think you get the idea, ... You might also consider using some GeneralData class or interface (within SomeClass) instead, and have getSpecificData() return a more specific (descended-)instance of it.
Again: This can be terribly misused to create very bad unreadable code, but it also can be used for very nice patters under the right circumstances, anyways it should answer the original question.
UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
If you want to restrict access to a single class, you can put them all in a new package. You will need to move the designated class that is allowed access into this packate, too. For the new classes, you can restrict access by using the default access level (no public/private/protected modifier). This will make them accessible only to the classes in their package. The specified class that is allowed access can be made public so that it can be used outside this new package.
Note: You have the option of restricting the visibility of the class or the visibility of the constructor.

Prohibit direct extension of Java class outside its package

I have a package with a
public abstract class Player { /*...*/ }
and these
public abstract class GamePlayer extends Player { /*...*/ }
public abstract class TournamentPlayer extends Player { /*...*/ }
public abstract class StatelessPlayer extends Player { /*...*/ }
Users of the package need Players but in order to use the package without breaking it I require that they never directly extend Player. Instead they should extend one of the subclasses provided.
Question: How should I prevent users from extending Player directly?
I'm looking for a way that makes it obvious that this prohibition is intended.
Make the constructors in Player have package access only. Then they won't be able to call the constructor or extend it themselves. If you don't already have an explicit constructor in Player, create one (as otherwise the compiler will create a default public parameterless constructor).
(Note that I've only suggested doing this to the constructor. The class itself can be public so that clients can still use it.)
This works because any constructor (other than in java.lang.Object) has to call a superclass constructor (either explicitly or implicitly). If there are no accessible constructors, you can't create the subclass.
Make sure the constructors of Player are not public:
public abstract class Player {
Player() {
// initialization goes here
}
}
Then classes can extend Player from within the same package, but should not be able to from outside of the package.
Um... make the Player class non-public? Just leave out "public", then it will be package-private, i.e. only classes in the same package can extend it.
However, nothing outright prevents people from putting their own classes in that package. I believe it's possible to prevent it by putting it into a signed JAR, then any attempt to load an unsigned (or differently-signed) class in the same package will fail.
Use the default access modifier, also known as "Package private" access. In other words, don't specify an access modifier
abstract class Player { /*...*/ }
The documentation here at Sun's website describes all of the access modifiers in greater detail.
I'd recommend
Create public interfaces for things you want clients to access but not create or subclass
Create public classes for things you want clients to access and create or subclass
anything else should be non-public
The problem with this approach is that you end up with everything needing to be in a single package, which is bad for organization as the library grows.
To allow use of multiple packages with protection, take a look at OSGi.
OSGi allows you to restrict which packages a bundle (jar) allows other bundles to access, and even set up "friend" bundles that are allowed extra visibility.
Java's package-as-protection-unit model is not sufficient when you really want to protect libraries that get large...

Categories

Resources