Java access specifier issue [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.
I am confused with access specifiers in Java.. I have a code with 2 different packages in Java.. But it displays an error every time I run it.. Here's is the code for the class which is calling the class using import from another package..
package p2;
import p1.Testing;
class Pqr extends Testing{ // extending the class
void hey(){
System.out.println("Something");
}
}
class Xyz{
public static void main(String args[]){
Pqr t1 = new Pqr(); // Class from another package.
System.out.println(t1.find("Mississippi","p"));
t1.hey();
}
}
Code for class which is being subclassed from package p1..
package p1;
class Testing{
protected static boolean find(String a,String b){ // Protected specifier
boolean ans = false;
for(int i=0;i<a.length();i++){
String m = a.charAt(i) + "";
if( m.equals(b)){
ans = true;
}
}
return ans;
}
public static void main(String args[]){
// Main Class
}
}
But when I run the code i get an error "Testing is not public in p1; cannot be accessed from outside package"..
I learned in this thread that we can use protected method between different packages but by extending it by another class.. In Java, difference between package private, public, protected, and private
Thanks in advance.

You don't have an access to the top-level class (in your case it's Testing), so you can't have an access to its members, no matter what are its access modifiers. You need to make Testing public to make its protected members visible from outside of its package to classes extending Testing. You can read more about it in Java tutorial. Here is a part about access modifier of Testing class:
A class may be declared with the modifier public, in which case that class is visible to all classes everywhere. If a class has no modifier (the default, also known as package-private), it is visible only within its own package
And the part about your find() method:
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
But to make use of protected members of class contained in another package, the class itself containing it need to be visible in another packages (it needs to be public).
Take a look at this Java tutorial for more informations about access modifiers:
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Related

Privately sharing variable only between two classes - Java [duplicate]

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.
I have a package that contains two classes. Private variable share is located in class A and that variable can be accessed only by these two classes, A and B, and can't be accessed by importing the package. Is it possible to achieve this?
// A.java
class A {
private static String share;
}
// B.java
class B {
public String myMethode() {
// do something with share
}
}
You cannot achieve it directly.
There are visibility levels in Java:
public - visible from any other classes
protected - visible in all classes who extend a class
so if in Class A you have
class A {
protected String share;
}
it will be visible in class B extends A, class C extends B and so on...
then there is a possibility to create another class D extends A and share will be visible in it. Unless class A is final, but with that you cannot have needed class B extends A
package visible
package com.foo.myclasses;
class A {
String share;
}
with that share will be visible in all classes in the package com.foo.myclasses
So still there is a way to create a class in the same package and share will be visible in it.
You may do a Work around to achieve that.
make private String share in class A
create protected getShare() (or package visible) method
and check the class like
protected String getShare() {
if (this.getClass().getName().equals("com.foo.myclasses.A") or this.getClass().getName().equals("com.foo.myclasses.B")) {
return share;
} else
{
throw new IllegalAccessException(this.getClass().getName() + " is not allowed to access share);
// or return null
}
}
But it is about access to the value of share at run time. Nothing prevents access (as above) in the code. Code will compile, but throws exception at run time.
It is what it is.

Member variables in a class are private by deafult? Why does my code still work? [duplicate]

This question already has answers here:
What is the default access specifier in Java?
(12 answers)
Closed 8 years ago.
Members of a class are private by deafult. The following code doesn't work.
#include<iostream.h>
class Test
{
int x;
};
void main()
{ Test test = new Test();
test.x=10;
}
However the same code works in Java?
class Test {
int x=5;
}
public class MyClass{
public static void main(String args[]) {
Test test = new Test();
System.out.println(test.x);
}
}
According to me it should not work.. since int x is private by deafult, it should not be available to MyClass.
I think the default modifier is package private. Thus you can use test.x in a class which is in the same package as class Test.
No visibility modifier does not indicate that the member is private. If members were private by default, why would the private keyword be allowed on members? That'd be rather redundant.
Instead, no visibility modifier on a member means that the field is package-private -- that is, only visible to other classes in the same package as the member.
Also, struct doesn't exist in Java. You might be getting confused with another language... The only place where members are public by default are interfaces (and maybe enums?), provided the containing interface/enum is also public.

JAVA Calling members (other class type) of inherited class from other package

I'm new to JAVA and im trying to understand how inheritance works.
I have 3 classes:
package dziedziczenie2;
public class Kobieta {
protected Oczy Eyes = new Oczy();
public static void main(String[] args) {
Kobieta x = new Kobieta();
System.out.println(x.Eyes); // blue
x.Eyes.kolor = "red";
System.out.println(x.Eyes); // red
}
}
class Oczy{
public String kolor = "blue";
public String toString(){
return kolor;
}
}
other package:
package dziedziczenie;
import dziedziczenie2.Kobieta;
public class Ania extends Kobieta{
public static void main(String[] args) {
Ania x = new Ania();
System.out.println(x.Eyes); // blue
x.Eyes.kolor = "red"; // type Oczy not visable
}
}
My questiong is, why i cant change Eye.kolor in Ania class simply my typing x.Eyes.kolor.
I know that Oczy is not public, but i can use its toString method somehow.
EDIT: Why i can use its toSting method and i cant use its member?
Do I have to make a method in Kobieta that will interact with Oczy member for me every time i want to interact with Oczy member from other package?
Thanks in advance
The class Oczy has access modifier "default" which is accessible only in the package "dziedziczenie2" n not in package "dziedziczenie".
1) Option:
You may simply create a file Oczy.java with declaring public class Oczy and u r done.
2) Option:
You may declare public static class Oczy in the class Kobieta like this.
public class Kobieta {
// ur code
public static class Oczy {
// ur code
}
}
Eyes is of type Oczy which has default visibility, since it has no access modifier. You can only access its members in the same package it's declared in, even if those are public.
Do I have to make a method in Kobieta that will interact with Oczy
member for me every time i want to interact with Oczy member from
other package?
You can do that or you can move the Oczy to its own compilation unit (.java file) and make it public.
If I understand correctly you are expecting Eyes to be inherited to Ania class.
Because in inheritance attributes are not inherited like methods. Eyes is attribute of Kobieta class so when Ania extends Kobieta it dont inherit it.

What is the point of "protected" word in Java if it gives you the same access rights as default access?

Can anybody explain me why do we need "protected" word?
If I understand correctly,
default access: available in classes within the same package.
protected access: default access in same package + available to inherited classes
(sub-classes) in any package. Basically, we get the same
default access in same package.
So when should I use it? Just for the style of your code? To mark it that you are going to work with it from perspective of inheritance?
Thank you.
package firstPack;
public class First {
protected int a;
protected void Chat(){
System.out.println("Here I am");
}
}
package secondPack;
import firstPack.First;
public class Second extends First{
public static void main(String [] args){
First f=new First();
// f.Chat();
// System.out.println(f.a);
}
}
I used this code to test it. It didn't work.
protected means visible to all sub-classes, not just those in the same package.
Problem with your test code is that you ware trying to access protected members of First class instance and via First class reference. Notice that since Second class is not in the same package as First one it doesn't have access to protected fields of any instance of base class, but have access to its own fields inherited from First class (which includes protected ones). So something like
First f = new First();
f.chat();//chat is protected in base class.
will not compile in Second class, but something like
public void test() {
a = 1; // have access to inherited protected field or
chat(); // methods of base class
}
public static void main(String[] args) {
Second f = new Second();
f.chat();
System.out.println(f.a);
}
is OK since Second class have access to its inherited members.
Notice that code in main method works only because it is placed inside Second class since only derived classes or classes in the same package as First have access to its protected members. So if this code will be placed inside other class like
class Test{
public static void main(String[] args) {
Second f = new Second();
f.chat();
System.out.println(f.a);
}
}
it will not compile (no access to protected members because Test doesn't extend or is not in same package as First).
The protected modifier: Accessed by other classes in the same package or any
subclasses of the class in which they are referred (i.e. same package or different package).
Reference

Java default access specifier is accessible outside the package?

I tried following piece of program and I came to know we can access default/package level instance variable.
I want to understand why it is allowed in java.
1.
package com.test;
class A {
public int i = 10;
}
2.
package com.test;
public class B extends A{
}
3.
package com.child;
import com.test.B;
public class C extends B{
public int getI(){
return this.i;
}
public static void main(String[] args) {
System.out.println(new C().getI());
}
}
I'm able to run this program successfully. What I want to understand is how it possible to access default access variable from another packkage.
Because it extends B which extends A.
B inherits all public members from A, regardless A's own visibility. That's why C sees the member too.
This is of course quite confusing. The root problem is that a public class extends a non-public class. Maybe the language should forbid that.
there are 4 different access levels: public, private, protected and package-private. Public is visible to everything, outside package even. Private is visible only inside class. Protected is visible to class and to all classes, that extends it. Package-private is default (when you don't specify any of others), and it is visible to all classes within one package, where the variable is initialized

Categories

Resources