in java I am confused on when to make a class public - java

I am going through head into java and came across this example
interface Nose{
public int iMethod();
}
abstract class Picasso implements Nose{
public int iMethod(){
return 7;
}
}
class Clowns extends Picasso{}
class Acts extends Picasso{
public int iMethod(){
return 5;
}
}
Because nothing is declared public, doesn't that mean that none of these classes can be called from another file? I have another file
public class Of76 extends Clowns{
public static void main(String[] args) {
Nose [] i = new Nose[3];
i[0] = new Acts();
i[1] = new Clowns();
i[2] = new Of76();
for(int x = 0; x < 3; x++) {
System.out.println(i[x].iMethod()+" "+i[x].getClass());
}
}
}
So in this example class Of76 can make classes out of another file that doesn't have any public classes. I am confused on why the first file can have all those classes and why they are not in separate classes. I read that a class that is not public is private by default, and can only be called within the same class. So everything in the Nose file can only be called inside that Nose file?

When you exlude public and don't have anything else there like protected or private this is called "package protected". This should explain the differences to you: In Java, difference between default, public, protected, and private

The answer to this question is a matter of perspective.
If you are a new Java learner and you are learning language features and the object-oriented paradigm, then a reasonable answer is "you should always make classes public" because visibility restrictions matter to nobody but you. Visibility is an issue only for production code or when you are exporting an API for other clients to use. It is not unreasonable to make classes public until you know how to write good classes (I would NOT extend this advice to fields of classes, however).
However...
If you are maintaining or modifying production code -or- developing an API that you intend to export for other programmers to use, then the best answer is "you should never make classes public unless your clear intent is that your clients should be able to access your class and use it in their own client code.
Visibility is one of the most important security and encapsulation mechanisms in Java and you should never be cavalier about it in a production environment. Everything in your API should have the lowest possible visibility.
There are some important exceptions that can be imposed upon you by other API's that you may be using. For example, if you are developing a controller class for JavaFX, then in JavaFX 2.2 you are required to make your class public, whether you want to or not. Even so, these exceptions do not break the rule that "everything in your API should have the lowest possible visibility."
TL;DR: If the code you're working on will be accessed only by you, then you need never make classes anything but public. If you're working on production code, code that will become available to others, or an API that you intend to export for client use, then you should never make classes public unless it is a clearly indicated part of your design.
public MyClass this class will be visible to classes in your package and classes in other packages.
protected MyClass this class will be visible to classes in your package and only other classes that are subclasses of MyClass.
MyClass this is "default access" or "package-private" access. MyClass is visible only to classes in the same package.
private MyClass this class is not visisble to other classes except those that are in the same .class file.
Default access and Private access are considered non-exported visibility levels. Classes with these visibility levels may be freely modified by you as their implementation details are not exported as part of any API.
Public and protected access are considered exported visibility levels. Generally, once you've exported a class as part of your API you are expected to continue to support it "forever".

Related

Why does Java 8 not allow non-public default methods?

Let's take an example:
public interface Testerface {
default public String example() {
return "Hello";
}
}
public class Tester implements Testerface {
#Override
public String example() {
return Testerface.super.example() + " world!";
}
}
public class Internet {
public static void main(String[] args) {
System.out.println(new Tester().example());
}
}
Simply enough, this would print Hello world!. But say I was doing something else with the return value of Testerface#example, for instance initializing a data file and returning a sensitive internal value that shouldn't leave the implementing class. Why does Java not allow access modifiers on default interface methods? Why can't they be protected/private and potentially elevated by a subclass (similar in how a class that extends a parent class can use a more visible modifier for an overridden method)?
A common solution is moving to an abstract class however in my specific case, I have an interface for enums, so that does not apply here. I imagine it was either overlooked or because the original idea behind interfaces that they are a "contract" of available methods, but I suppose I want input as to what's going on with this.
I've read "Why is “final” not allowed in Java 8 interface methods?", which states:
The basic idea of a default method is: it is an interface method with a default implementation, and a derived class can provide a more specific implementation
And it sounds to me like visibility wouldn't break that aspect at all.
As with the linked question since it looks like it had trouble being closed, an authoritative answer would be appreciated in this matter, rather than opinion-based ones.
As we saw in What is the reason why “synchronized” is not allowed in Java 8 interface methods? and Why is "final" not allowed in Java 8 interface methods?, extending interfaces to define behavior is more subtle than it might first appear. It turns out that each of the possible modifiers has their own story; its not simply a matter of blindly copying from how classes work. (This is at least obvious in hindsight, as tools for OO modeling that work for single inheritance do not automatically work for multiple inheritance.)
Let's start with the obvious answer: interfaces have always been restricted to only having public members, and while we added default methods and static methods to interfaces in Java 8, that doesn't mean we have to change everything just to be "more like" classes.
Unlike with synchronized and final, which would have been serious mistakes to support for default methods, weaker accessibilities, especially private, are reasonable features to consider. Private interface methods, whether static or instance (note that these would not be defaults, since they do not participate in inheritance) are a perfectly sensible tool (though they can be easily simulated by nonpublic helper classes.)
We actually did consider doing private interface methods in Java 8; this was mostly something that just fell off the bottom of the list due to resource and time constraints. It is quite possible this feature might reappear on the to-do list some day. (UPDATE: private methods in interfaces were added in Java 9.)
Package and protected methods, however, are more complicated than they look; the complexity of multiple inheritance and the complexity of the true meaning of protected would interact in all sorts of no-so-fun ways. So I wouldn't hold your breath for that.
So, the short answer is, private interface methods is something we could have done in 8, but we couldn't do everything that could have been done and still ship, so it was cut, but could come back.

JAR-Level (Assembly-Level) Class Scoping in Java

In C#, if I want a class to be visible to any class within that assembly (DLL), I simply scope it as internal (which is the default).
How can I do this in Java? In Java, I've noticed the default/internal scoping is package level, not JAR level. This is a problem for me, since I have a library that has several sub-packages with different responsibilities (view, controller, etc.) and can't put them in the same package.
As an example, I have two classes like com.stackoverflow.main.first.One and com.stackoverflow.main.second.Two, both of which should be able to instantiate each other.
Edit: I don't want the class to be public and visible from anyone who references it. It's an internal class only. I'm creating an API for consumption, and of primary importance to me is which classes can be seen by consumers of my JAR.
Java has no concept of library-level scoping. Make the classes public or use a factory.
To accomplish what you want, you'll have to use some mix of a factory pattern to create the classes you want to expose and leave the private classes package private. Usually, I've done this:
create the public interface for the API in a package like com.foo.bar a la public interface Foo {}
create a factory class that exposes a create method a la:
public class FooFactory{
public Foo buildFoo(){ return new FooImpl(); }
create FooImpl as a package private class - class FooImpl implements Foo{}
Document package to indicate proper usage.
It's not perfect, but until the JSR about module scoping progresses, it's probably the closest you can get in java. If you want to ensure that FooImpl doesn't get inappropriately extended, be sure it is marked final.
sounds as simple as you have to use the public access modifier.

Non-public top level class in Java

What's the reason of making top-level class non-public in Java?
Let's say we have Foo.java, there could be
class Foo {
}
or
public class Foo {
}
I understand that there will be some class - visibility issues with the former example (probably it won't be visible from other packages). But anyway, are there any reasons why someone may want to do as in the first code sample?
UPD: What cons I see in the former solution: nobody cares that it's non-public. That class can be simply extended by some other public class in the same package later, then, non-public part of the class may bring you visibility/access issues.
Here is an example.
No one needs to know about existence of our ConcreteDocument.
DocumentIF.java
public interface DocumentIF {
}
ConcreteDocument.java
class ConcreteDocument implements DocumentIF {
}
DocumentFactory.java
public class DocumentFactory {
public DocumentIF createDocument() {
return new ConcreteDocument();
}
}
Typically, you make a class package-private because you don't want the class to be used outside the package. When a top-level class isn't public, it's private to the package.
Say you have a package with a number of classes that must communicate the same sort of data with one another. But this data structure is an implementation detail and so you don't want it being used by user code. Making the transfer class package private maintains this sort of package level encapsulation.
I understand that there will be some class - visibility issues with the former example (probably it won't be visible from other packages).
That seems to me to be reason enough to use it if you want to keep the class private to that one package.
Just noticed another use! It seems you can only have one public top-level class per code file, but any number of non-public top-level classes. Haven't verified it personally, but if true that could be quite useful to prevent cluttering your project folder and to group classes with related functionality that aren't needed outside of the package.
Classes without a public or protected modifier are only visible inside the package they reside. If you think of components and interfaces there is a reason for leaving out the public modifier. Let's say you have a public class MyCompontent that internally uses other classes, but does not want to publish those to the outside world (users of the component) it makes sense to leave out the visibility modifier.
It is considered good design to keep the visibility of a class to the most minimum required. The reasons that I can think of:
The class can easily change in the future without causing breakages in external packages as the external packages do not have access to the class. In this regard it might be even better to start off a class by making it a private inner class.
The class being package visible cannot be extended by classes in external packages. This again makes it easier for this class to change without causing breaking changes in external packages. If this class was not meant to be extended then it would be even better to make this final.
A public visible class becomes a part of the exported API of your library. If you are a library designer, it is better to keep your exported API as small as possible because you do not want to confuse your consumer with un-necessary classes/details. Item 1 would again hold good in this case.
The book "Effective Java" by Josh Bloch is an excellent reference for Idiomatic Java code and design.

Question on the nature of inherited Java classes

So I think I have a pretty basic question. Say there's an open source Java program called com.cow.moo that you include in your project com.bee.buzz.
moo has a bunch of great classes, most of which you don't want to touch, but there are a couple you do. Now at this point, the best thing to do would be to extend the classes you want to modify, right? (I know there's been a lot said of extends vs. implements, but none of these classes are interfaces, so that's kind of out of the question.)
My question is, say this is the class in moo:
package com.cow.moo;
public class Milk {
private float currentMilk;
public int getMilk() { /* Stuff */ }
public float convertToGallons (float liquid) { /* More Stuff */ }
}
Now, say I want to just use getMilk in my new class that extends Milk. However, getMilk in Milk relies on private variables (like currentMilk) and other functions I won't be including (like convertToGallons.) Will I have to include those other variables and functions if I want my new function to work correctly? I don't want to heavily modify the function, just add a little bit to it. What's the best way to do this?
Tips in general in building off a larger project would be useful, too. I figure it won't even take five seconds for some of the Java experts here to come up with an answer. Thanks for your time.
The general recommendation is to favor composition over inheritance.
Say, you have an interface and an existing implementation that mostly fits you needs, like
public interface MilkProvider { public float getMilk(); }
public class Milk implements MilkProvider { // same as you example }
and need another custom implementation, you could code it like that:
public class MyMilk implements MilkProvider {
private MilkProvider milk;
public MyMilk(int someValue) {
milk = new Milk(someValue); // unfortunatly we can't get rid of a depencency
// to the concrete class because we need to create
// something. An existing factory could help, but
// but usually there's none implemented.
}
public float getMilk() {
float result = milk.getMilk();
// do somethink with the result
return float;
}
}
Now, say I want to just use getMilk in my new class that extends Milk. However, getMilk in Milk relies on private variables (like currentMilk) and other functions I won't be including (like convertToGallons.) Will I have to include those other variables and functions if I want my new function to work correctly?
You won't have to include the public functions and variables. The core concept of inheritance is that, as a subclass, you get all of your parent class's public (and protected) members included in your subclass for free. So your subclass (let's say HoneyMilk) can call convertToGallons right from the get-go.
Overriding getMilk in this case is a lot trickier, since it relies on a private variable (which your subclass cannot access). My advice is to shift your mindset from treating the class as a "white box" to a "black box". What I mean by that is that you should implement your overridden version of getMilk as if you weren't actually able to see Milk's source code. While it may seem like a roundabout solution (I mean, why can't I just go tweak this line here?!), this will force you to implement your subclass using only what the parent class exposes publicly. It also heavily emphasizes the importance of abstraction, which is absolutely crucial to utilize when developing large-scale projects.
I think in this case better solution will be polymorphism (static polymorphism), or you can use reflection (do not use this way) to reach to the private variable.
You can extend the class and access instance variables throught method accessors (getters & setters) if they are public.
You can use AOP (Aspect Oriented Programming) to change your moo classes at runtime without changing its sources.
Consider too read some Composition vs. Inheritance topics.
Hope this will help you.
You won't be able to use private class members unless you use Java reflection which will be kind of ugly. If I were you (and the changes are not too heavy, in which case I'd fork the original project), I'd look at modifying the code at runtime or statically using aspect weaving (aspect oriented programming). AspectJ may look as if it had a sharp learning curve, but it's a great tool to have in your toolbox and perfectly matches your needs here.

Implementing friend (available in C++) functionality in Java [duplicate]

This question already has answers here:
Is there a way to simulate the C++ 'friend' concept in Java?
(18 answers)
Closed 9 years ago.
Ok, let's leave the debate of whether friendship breaks encapsulation, and actually try elegantly come up with a coherent design. It is a two fold function:
1) General question on how to implement:
public class A
{
friend class B;
}
2) Why do I need this functionality? Some of my classes implement Serializable interface. However, I want to make Serializable methods protected in the Derived class so that I don't expose them to a client (as well as in the documentation -- javadoc). However, internal classes should be able to access them. What is the General way to solve this problem in java?
Note: I am using friendship as defined in the current C++ standard.
Thanks
The general solution is to make the methods package-private (which is the default protection level in Java). That way any code in the same package can access them, but not external code.
Java does not allow arbitrary sharing of methods with specific external classes.
EDIT: Protected members are actually less private than package-private. If you have protected members, you can access them from derived classes outside your package, and from any class inside the package. So that may be a solution to your problem - derive the class in another class in the package you want to export to.
Generally, Java considers the package as the main module of encapsulation. The public/protected interface is for classes outside the package, and the default protection level allows access within the package.
It seems as if you want a façade.
You appear to have a class that needs to give public access to various other classes (even in different packages) involved in the implementation. But you don't want clients having access.
Therefore, make the implementation as complicated as you like. Have a façade class, with just the interface you want, delegate to the implementation.
This link gives a way to emulate friend access in Java: http://macchiato.com/columns/Durable7.html
The code copied from the link (in case the site is not accessible):
public class A {
private int privateInt = 31415;
public class SomePrivateMethods {
public int getSomethingPrivate() { return privateInt; }
private SomePrivateMethods() {} // no public constructor
}
public void giveKeyTo(B other) {
other.receiveKey(new SomePrivateMethods());
}
}
public class B {
private A.SomePrivateMethods key;
public void receiveKey(A.SomePrivateMethods key) {
this.key = key;
}
public void usageExample() {
A anA = new A();
//int foo = anA.privateInt; // doesn't work, not accessible
anA.giveKeyTo(this);
int fii = key.getSomethingPrivate();
System.out.println(fii);
}
}
One thing I noticed... it sounds like you do not want the methods that you have to override because you are implementing Serializable to be made public. One thing though, Serializable is a marker interface (it provides no methods to be overridden) and the readObject and writeObject methods are supposed to be private.
Am I missing something?
There are two solutions to your question that don't involve keeping all classes in the same package.
The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).
The second is to use OSGi. There is an article here explaining how OSGi accomplishes this.
Related Questions: 1, 2, 3, and 4.

Categories