I am beginning to learn the principles of OOP and inheritance, and I came across this question while writing some code:
Suppose there is a package which contains a class called ClassA. Then, in a separate folder, I have another class called MyClass. Inside the same folder as MyClass, I have another class called ClassA, which is unrelated to the ClassA in the package. When I write the code for MyClass, I make it extend ClassA.
Which ClassA does MyClass extend from? Does MyClass inherit the ClassA which is in the imported package, or does MyClass inherit the ClassA which is in the same folder as MyClass? Would the code even compile?
I am trying to understand this from a theory perspective before diving into examples.
what you're looking at is a Statically scoped language which will work its way out of its inner scope, all the way to its outter scopes.
In this case, since import Class A is declared directly inside the file to which it is first called, it will use import Class A and stop.This will be its default behavior.
It will not carry on to look at the packaged Class A because it found one already, declared inside of the same class file.
This is the default behavior of java's (static) scope hierarchy.
IF it had not found an import of Class A imported inside the same file, it would reach out to its package to search for one.
This is very useful when declaring like variables. Do a little research how statically scope languages work.
If it is easier for you to understand, you can be explicit in your intentions by declaring exactly which Class A you would like though.
Just a side note- this is more of a programming languages question than directly a java question, but since you ask specifically for java, we only need to cover the simple specific answer. if you would like to know more, i can direct you (or tell you) more about statically vs dynamically scoped languages.
I suppose it is worth noting that if you decide to import both Class As even from your package (which you do NOT need to do) you would have to explicitly declare which you would like.
In that situation, to make it perfectly clear to the compiler you would probably want to do something like extends otherPackage.ClassA, and use the full reference name to extend the classA from the other package. If you want to use the one from the package MyClass is in, then just don't import the other ClassA and do extends ClassA
Since you're new to programming, I'm going to explain it in really simple words. Say there is a package called Salads. In that package, you have a class called Caesar. Then, you have another package called People. In that package, you have another class called Caesar. Obviously, Salads.Caesar refers to Caesar salad, and People.Caesar refers to a person named Caesar. But both classes have the same name: Caesar.
So when you're writing java code, java looks in two places for class definitions:
classes defined in the same folder (because they are implicitly in the same package if they are in the same folder assuming you're following all the normal rules.
classes defined in any imported packages
So the question is asking if you just say Caesar in the code, will it recognize it as the one in the same folder or the one in the imported package? Well, this is a bad question to ask because first of all, you should not name your classes so ambiguously. Secondly, if it can't be helped, you should always refer to the fully qualified name in your code.
If you mean People.Caesar then type People.Caesar and if you mean Salads.Caesar, type Salads.Caesar. Don't take shortcuts. You can only take shortcuts if there is no ambiguity. The compiler will probably complain about it anyway asking you to specify. AKA your code will not work unless you change all references of Caesar to Salads.Caesar or People.Caesar.
Packages in Java is a mechanism to encapsulate a group of classes,
interfaces and sub packages. Many implementations of Java use a
hierarchical file system to manage source and class files. It is easy
to organize class files into packages. All we need to do is put
related class files in the same directory, give the directory a name
that relates to the purpose of the classes, and add a line to the top
of each class file that declares the package name, which is the same
as the directory name where they reside.
in the top of java files, you have import that you can choose what class from what package you mean of course as #Jason said too if the class you want its in your package you don't need to tell it explicitly and compiler know that but if its in another package you have to tell him explicitly.
assume you have FirstClass.java in src folder and another in mycodes folder when in your class you import FirstClass you mean FirstClass.java that exist in src folder and when you import mycodes.FirstClass you mean FirstClass in mycodes folder.
your class can be member of packag.when you extend class that you class are in package A when you extend SomeClass you mean SomeClass that is in package A and if you want extend other class that is in other package like B you must extend B.SomClass
Here is another information about packages in java
Related
I am trying to call a public constructor of a public class located in one package of my project from the main class, located in a class from another package different to the first one, but located in the same project.
I have understood that the public modifier grant you access to methods from any location inside or outside the package, so i just try to create and instance a new object of the public class first mentioned.
F.E: I try something like.... ClassName newObject = new ClassName(); from the main class
Actually, in order to be able of using that (im using netbeans IDE) I need to import the class/method I want to call, even if they have the public modifier.
My question is... is there a way of using these methods without the need of importing them to the main class ?
I am new in this webpage, so sorry if there is anything wrong with the question.
Qualification and visibility have little to do with eachother. Those are different concepts.
Visibility (enforced by access modifiers like public, protected, private and package-private) is about which class may access (i.e. call or use) it.
Qualification is about the compiler asking you: "Okay, you are mentioning a class name, but there could be thousands around with that name. Which one do you mean?"
You could use the fully qualified class Name instead.
a.b.c.MyClass myClass = new a.b.c.MyClass();
Also see
Java: import statement vs fully qualified name?
Java compiler restricts its search for classes inside the package only. In order to make use of any class belonging to a different package, you have to import it explicitly. You can read more about packages here.
Access specifiers are more from restricting the methods from being accessible by outside world. These access specifiers enforce further restrictions on top of what is enforced by packages. You can refer to this link for access specifiers.
I have a question about a sneaky way to gain access to package-access members that occurred to me. Specifically, I want to extend a class - let's call it com.acme.Foo - to add some functionality. This is pure addition: all current methods of Foo would be supported just by delegating to the superclass's method. However, there is no accessible constructor of Foo, so I can't extend the class and my implementation won't pass the "isA" test for being a Foo. There is no interface that expresses Foo-ness that I can use instead of inheritance.
This is where the sneaky thought occurred to me: Foo has a package-access constructor, so why not just create a package com.acme in my source folder and create an InheritableFoo class in that package:
package com.acme;
public class InheritableFoo extends Foo {
public InheritableFoo() {
super();
}
}
Now I can implement my extension to Foo by extending InheritableFoo, since that DOES have an accessible constructor.
This feels all wrong, and somehow unethical: I'm not respecting the decision the original programmer made when he or she decided to not expose a constructor for Foo. But it could be the case that they simply adopted the "deny everything until there's a reason for it" approach. Either way, is there anything fundamentally wrong with this idea? Am I going to cause myself problems in the future if I go this route, and if so, why?
You are correct regarding the fact that you can "sneak" in a class of your own into another package and get access to package restricted elements.
This will however only as long as the author of com.acme.foo distribute his code as source or an unsealed package. Should the author of this package distribute it as a sealed jar (which is quite common I believe) your approach will no longer work.
From Sealing Packages within a JAR File
Packages within JAR files can be optionally sealed, which means that
all classes defined in that package must be archived in the same JAR
file.
Considering everything is object oriented etc, so names have to describe the object and what it is, I have an abstract class that sub classes inherit from. These are all objects on the screen (it's a game), i.e, player, and a weight (trapezoid weight). I have it currently named Character but it doesn't seem fitting as the weight is not a Character itself, it only inherits properties from Character.
Could I call this class "Object" without it breaking conventions? - could someone come up with a more appropriate name?
Technically, you could - but it's a very, very bad idea, so don't.
Longer explanation: The Object class already in Java is java.lang.Object - so there's no technical reason why you could create another Object class in another package, just as you could create another String class in another package. (Actually, technically speaking you could even create your own java.lang.Object, but I'm not even going to go there!)
However:
Could I call this class "Object" without it breaking conventions?
Without breaking convention? Not in the slightest. You should never duplicate such commonly used class names elsewhere, especially those in java.lang. It would be considered incredibly bad code design.
In terms of a better name, Actor or Sprite may be two good alternatives.
Java's Object class is part of the java.lang package which is automatically imported for every class file. If you name your class Object and forget to explicitly import it in other classes, you will have issues, thinking you're using com.custom.Object (your class), but actually using java.lang.Object, the JDK's.
Use a more descriptive name, ApplicationObject.
Yes you can. The class beside the name has the path that is package.
package org.stackoverflow
public class Object {
}
By default java.lang is prohibited package name so you can not do declare
package java.lang
public class Object {
}
The class names does not have to be unique in scope of whole world. Using the class path you are able to override the JVM definition of class.
I'm developing a library which the other programmer will import and use it for their purposes.
I'm confused about the objective of Java access modifier.
The problem is that I have classes below
ClassA in package org.mylibrary
ClassB in package org.mylibrary.internal
ClassA needs to resolve ClassB so ClassB need to be public class.
However, from library user view, I don't intend ClassB to be visible outside my library. Because it shouldn't be and don't need to be initiated by the user.
I think of moving ClassB to package org.mylibrary and make it package-private class.
If I move it to the same package, it would be a mess and difficult to organize because I have many classes in this scenario so there will be many .java files in a big one package.
Normally I put the classes in packages grouped by category or layer and I think it's easy to organize.
How do I do this? How do people handle this problem?
It is difficult to give concrete advice since you give so little info about the roles of and relationship between ClassA and ClassB. However, one general solution (which is almost always used as part of eliminating dependencies) is to hide ClassB behind an interface. Then ClassA uses only that interface, so it is not anymore directly dependent on ClassB. ClassB can be made package private, its instances produced by e.g. a factory, or dependency injected into ClassA.
Assuming ClassB is a test package with unit tests:
Why does ClassB need to use it. Normally test classes use the regular classes, not vice versa.
In general, the recommendation for test classes is to put them into the same package as the regular classes, but maintain the .java files in a parallel directory hierarchy (i.e. you have src/org/mycompany/MyClass.java , and test-src/org/mycompany/MyClassTest.java ). That way, to Java both are in the same package and can access each other, and for release builds you just don't compile the test classes (or don't even check them out) - that way everything is nicely separate.
If this does not apply in your case, maybe you could edit your question with more detail?
It would be a mess and difficult to
organize because I have many classes
in this scenario.
Do you mean that the java file look messy? You can split the internal classes in a different .java file.
ClassA.java
package org.application;
public class ClassA {
}
Internal.java
package org.application;
class ClassB {
}
class SomeOtherInternalClass {
}
Hope this helps.
i think i understand your question, and the answer is that there is no way to do that in java up to now!
there are some tricky ways but they invovle dirt coding.
look here
http://openide.netbeans.org/tutorial/api-design.html#design.less.friend
I plan to extend a JSF renderer. The package name is oracle.adfinternal.view.faces.renderkit.rich
Should the extended class be in the same package structure:
oracle.adfinternal.view.faces.renderkit.rich
or even oracle.adfinternal.view.faces.renderkit.rich.[subpackage]
or can/should I put it into my own package? com.company.renderkits.
I suppose package-private variables might be interfered with if I put this into my own package name?
Any thoughts?
In general, you should put your extended classes in your own package.
The package-private access level should be used by closely connected classes, possibly written by the same developer, who knows all the implementation details. This is not the case if you extend a class with some functionality.
All that said, there are a few occasions where you need to place your class in the package of the superclass as a workaround, but remember, this is an ugly hack, and try hard to avoid it.
You should put the class into your own package. There shouldn't be any compilation/access problems. The superclass already sees what it needs to see.
I suppose package-private variables might be interfered with if I put this into my own package name?
This is true, but normally the extending class shouldn't worry about this. The to-be-extended class would have used the protected modifier for this otherwise.
You should not add things to other entities (companies, person) packages. They could make a class with the same name (and same package of course) at a later date. They could also choose to seal their JAR files as well which would prevent you from adding classes to their packages.
The purpose of packages is to give each entity their own unique namepsace in which to create types.
In your case I would name the package something like: com.foobar.oracle.adfinternal.view.faces.renderkit.rich where "com.foobar" is the reverse domain name of your entity (if you don't have one pick something that is unique).