If a class has the visibility package private, is there any point to also set the methods to have that visibility since you can't access the methods in the first place?
The package private class for example may implement some interface and be used outside of its package. In that case implemented methods should be public. Also you might what to restrict usage of some members in the same package by private access modifier.
package pkg1;
public interface SomeInterface {
void m();
public static SomeInterface getImplementation() {
return new A();
}
}
class A implements SomeInterface {
#Override
public void m() {}
public void m2() {} // this one cannot be called from other packages
private void m3() {} // this one might be used only in class A
}
package pkg2;
import pkg1.SomeInterface;
public class Main {
public static void main(String[] args) {
SomeInterface implementation = SomeInterface.getImplementation();
implementation.m();
}
}
Simple answer yes if a class is going to be implemented or extend. No if it is not going to be extend or implemented. How ever I highly recommend to still make methods or variables you don't want other classes to see be private. This will save time later on if you wish to change the classes visiablity, along with making the code more readable in the long run.
Related
I know the difference between all the access modifiers in Java. However, someone asked me a very interesting question that I struggled to find the answer to: What is the difference between a private interface and a public interface in Java, in particular, how it is used as a class member? Any help would be greatly appreciated.
I believe we all know the use of public interface, so I would mention the point of private/protected interface here.
Interfaces can be members of class definitions and can be declared private or protected there.
public class Test {
private interface Sortable {
}
protected interface Searchable {
}
}
Example 1: -- Source
public class PrivateInterface {
private interface InnerInterface {
void f();
}
private class InnerClass1 implements InnerInterface {
public void f() {
System.out.println("From InnerClass1");
}
}
private class InnerClass2 implements InnerInterface {
public void f() {
System.out.println("From InnerClass2");
}
}
public static void main(String[] args) {
PrivateInterface pi = new PrivateInterface();
pi.new InnerClass1().f();
pi.new InnerClass2().f();
}
}
/* Output:
From InnerClass1
From InnerClass2
*/
It's the interface itself that can be package-private, not the methods
in it. You can define an interface that can only be used (by name)
within the package it's defined in, but its methods are public like
all interface methods. If a class implements that interface, the
methods it defines must be public. The key thing here is that it's the
interface type that isn't visible outside the package, not the
methods.
The public, private, and protected access modifiers on an interface mean the same thing that they mean on a class. I typically see these modifiers used on an interface that is nested in a class. Something like this:
//: interfaces/RandomWords.java
// Implementing an interface to conform to a method.
package interfaces;
public class PrivateInterface {
private interface InnerInterface {
void f();
}
private class InnerClass1 implements InnerInterface {
public void f() {
System.out.println("From InnerClass1");
}
}
private class InnerClass2 implements InnerInterface {
public void f() {
System.out.println("From InnerClass2");
}
}
public static void main(String[] args) {
PrivateInterface pi = new PrivateInterface();
pi.new InnerClass1().f();
pi.new InnerClass2().f();
}
}
An interface declaration may include these access modifiers:
public protected private abstract static strictfp
public: If an interface type is declared public,then it can be accessed by any code.
protected/private: The access modifiers protected and private pertain only to member interfaces within a directly enclosing class declaration. A member interface is an interface whose declaration is directly enclosed in another class or interface declaration.
static: The access modifier static pertains only to member interfaces, not to top level interfaces.
abstract: Every interface is implicitly abstract. This modifier is obsolete and should not
be used in new programs.
strictfp: The effect of the strictfp modifier is to make all float or double expressions
within the interface declaration be explicitly FP-strict.
Ref: Java Language and Virtual Machine Specifications
I have a class with no modifier(default), which has a public method called mymeth. I know I could access the method when I am within the package. However I would like to access the method when I am outside the package. does anyone has an Idea on how it could be done. theoretically I think it should be possible since public method means access by the world. here is the example of my class and method:
class myclass{
public void mymeth(int i,int b){
.....
}
}
set myclass class to be public.
**FYI, Classes in Java start from upper Case letter
Directly you cannot. 'public' makes everything visible. But if you can't see the class, it's difficult to call anything. However,
You can extend the default class with a public class, eventually myMeth is exposed.
PubClass.java
package p1;
class DefClass{
public void myMeth(){
System.out.println("from myMeth!");
}
}
public class PubClass extends DefClass{
public PubClass(){
super();
}
}
MainClass.java
package p2;
class MainClass {
public static void main(String[] args) {
p1.PubClass pub = new p1.PubClass();
pub.myMeth();
}
}
output:
from myMeth!
A real practical use for this would be, overriding a public known method in that hidden class. You can implement a public method in a hidden class, so the world can call your public method (public implementation rather) without the class being exposed. For example the public method of the Object class is overridden here by DefClass:
PubClass.java
package p1;
class DefClass{
public String toString(){
return "DefClass here. Trying to explain a concept.";
}
}
public class PubClass extends DefClass{
public PubClass(){
super();
}
}
MainClass.java
package p2;
class MainClass {
public static void main(String[] args) {
p1.PubClass pub = new p1.PubClass();
System.out.println(pub.toString());
}
}
output:
DefClass here. Trying to explain a concept.
public interface SomeInterface{
public void mymeth();
}
class MyClass implements SomeInterface{
public void mymeth(){
}
}
//is in the same package as MyClass
public MyClassFactory{
public SomeInterface create(/*parameters*/){
//create instance from parameters
//For your case
MyClass instanceOfAnyClassThatImplementsSomeInterface = new MyClass(/*pass the parameters*/);
return instanceOfAnyClassThatImplementsSomeInterface;
}
}
One of the ways is already defined in answers but If you want to restrict the public access of the class then you can create an interface and access the method through it.
Set myclass as public then put it in the build path of the class you need to use myclass.
In your code, myclass has the default (package-level) access modifier. It should be declared using the public access modifier so that it is accessible outside its package. For details, read more about Controlling Access in Java.
As a side note, the Java standards require you to capitalize each word in the class name, so you should use MyClass. I recommend you the Java Conventions document.
Consider making another public class MyChild with the same package name as MyClass and expose the method from MyChild class
public class MyChild extends MyClass {
public void myTestMethod(){
super.myTestMethod
}
}
Now in your class where you want to use the method, simply use the instance of MyChild class
MyChild m = new MyChild();
m.myTestMethod();
Cheers :)
I wonder if it makes any difference if a method is public or package protected in a class that is package protected.
class Example {
public void test() {}
}
instead of
class Example {
void test() {}
}
I guess the maximum visibility is given by the class. And a method can only reduce the visibility and increasing the visibility has no effect.
But it's valid syntax, so perhaps I've overseen something?
If we subclass Example to a public class , then code outside the package can access test() method using the subclass instance if it is public .
Example:
package A;
class Example {
public void test() {}
}
package A;
public class SubExample extends Example {
}
package B;
import A.SubExample;
class OutsidePackage {
public void some method(SubExample e){
// Had test been defined with default access in class Example
// the below line would be a compilation error.
e.test();
}
}
If Example implemented an interface of some kind you'd have to make them public, because you can't reduce access in that case. All interface methods are, by default, public.
As written, it does nothing. If it's a subclass or interface implementation, then it may be implementing or overriding methods that are declared public elsewhere.
I have inherited a particular class hierarchy of singletons whose declarations are summarized below (there are more implementations -- I'm just showing the minimal set to demonstrate the problem). It smells to high heaven to me, foremost because singletons are being inherited from, as well as the way instance in the base class has its value overwritten in the static initializers of the subclasses.
If all the implementations were in the foo.common parent package I would consider just dropping the instance member and getInstance() methods from them, making the classes and their constructors package-local, and having some public factory class in foo.common create a single instance of each, hold onto that single instance of each internally (partitioned by whether it was an implementation of IReadOnly or IReadWrite) and provide a couple of public lookup methods where based on some enum it would return the asked-for implementation as the interface type.
But implementations can be outside of foo.common and foo.common isn't allowed to depend on such "more specific" packages, since foo.common is intended for stuff common to a bunch of apps. So something that simple can't be done. What then?
First interface:
package foo.common.config;
public interface IReadOnly
{
void load();
String getVal(String key);
}
Second interface:
package foo.common.config;
public interface IReadWrite extends IReadOnly
{
void save();
void setVal(String key, String value);
}
First implementation:
package foo.common.config;
public class ReadOnlyImpl implements IReadOnly
{
protected static IReadOnly instance;
static {
instance = new ReadOnlyImpl();
}
public static IReadOnly getInstance() {
return instance;
}
protected ReadOnlyImpl() {}
// implement methods in IReadOnly
}
Second implementation
package foo.common.config;
public class ReadWriteImpl extends ReadOnlyImpl implements IReadWrite
{
static {
instance = new ReadWriteImpl();
}
public static IReadWrite getInstance() {
return (IReadWrite) instance;
}
protected ReadWriteImpl() {
super();
}
// Implement methods in IReadWrite
}
Third implementation:
// While things in this package can depend
// on things in foo.common, nothing in
// foo.common is allowed to depend on this package.
package foo.apps.someapp;
public class MoreSpecificReadWriteImpl extends ReadWriteImpl
{
static {
instance = new MoreSpecificReadWriteImpl();
}
public static IReadWrite getInstance() {
return (IReadWrite) instance;
}
protected MoreSpecificReadWrite() {
super();
}
// Override superclass methods to do something specific
}
Putting package foo.apps.someapp aside, the design of the package foo.common.config is wrong.
IReadOnly o1=ReadOnlyImpl.getInstance(); // ok, returns ReadOnlyImpl
...
ReadWrite o2=ReadWriteImpl.getInstance(); // ok, returns ReadWriteImpl
...
IReadOnly o3=ReadOnlyImpl.getInstance(); // bad, returns ReadWriteImpl, the same as o2.
The reason is that all classes use the same static variable ReadOnlyImpl.instance. I would use separate variable in all classes, including MoreSpecificReadWriteImpl. If this would not fit, then think of using Spring container or similar framework.
I know it is not a good coding practice to declare a method as private in an abstract class. Even though we cannot create an instance of an abstract class, why is the private access modifier available within an abstract class, and what is the scope of it within an abstract class? In which scenario is the private access specifier used in an abstract class?
check out this code where Vehicle class is abstract and Car extends Vehicle.
package com.vehicle;
abstract class Vehicle {
// What is the scope of the private access modifier within an abstract class, even though method below cannot be accessed??
private void onLights(){
System.out.println("Switch on Lights");
}
public void startEngine(){
System.out.println("Start Engine");
}
}
Within is the same package creating a Car class
package com.vehicle;
/*
* Car class extends the abstract class Vehicle
*/
public class Car extends Vehicle {
public static void main(String args[]){
Car c = new Car();
c.startEngine();
// Only startEngine() can be accessed
}
}
Since an abstract class can contain functionality (as opposed to an interface) it can have private variables or methods.
In your example you might do something like
public void startEngine(){
injectFuel();
igniteSpark();
// etc. my understanding of engines is limited at best
System.out.println("Start Engine");
}
private void injectFuel() {}
private void igniteSpark() {}
That way you can spread some of the work to other methods (so you don't have a 1000 line startEngine method), but you don't want the children to be able to call injectFuel separately since it doesn't make sense outside the context of startEngine (you want to make sure it's only used there).
Or even more you might have a private method that gets called in several other public methods, with different parameters. This way you avoid writing the same code twice or more in each of the public methods, and grouping the common code in a private method makes sure the children don't access it (like they couldn't just call part of the public method before). Something like this:
public void startEngine() {
dishargeBattery(50);
System.out.println("Start Engine");
}
public void startRadio() {
dischargeBattery(20);
}
private void dischargeBattery(int value) {
battery.energy -= value; //battery should probably be a private field.
}
This way your methods can have access to the battery, but the children shouldn't mess with it, and you don't write the same line (battery.energy -= value) in both of them. Take note though, that these are very simple examples, but if dischargeBattery was a 500 line method, writing it in both the other methods would be a hassle.
It's the same as in a non-abstract class, there's no difference.
Which means that if nothing in your abstract class calls the private method, then you can just as well remove it, as it won't be called (baring some evil reflection work).
Usually, private methods are only used as internal utility methods that have a very specific task that the other methods in the class use to do their work.
I know it is not a good coding
practice to declare a method as
private in an abstract class.
I don't. Where did you get that idea?
what is the scope of it within an abstract class?
The abstract class.
The method can be accessed only from within the abstract class. For example, you could have an abstract class with a public final method that makes use of a private helper method.
package arrayafter;
public abstract class Abstract_Demo {
abstract void display();
private void display1() {
System.out.println("Private Method");
}
final void display2() {
System.out.println("final Method");
display1();
}
public static void display3() {
System.out.println("Static methods");
}
}
package arrayafter;
import java.util.Scanner;
public class Practice extends Abstract_Demo{
public static void main(String[] args) {
Practice pr=new Practice();
pr.display();
pr.display2();
Abstract_Demo.display3();
}
#Override
void display() {
// TODO Auto-generated method stub
System.out.println("Abstract method");
}
}