about same class names and interface names in a package - java

I am little bit confused of classes names.This is my problem ...i tried to give same class name in two different files and in the same package with default access modifier and even i tried with interfaces even then it is not showing any errors.i want to how they are actually accessed.
i dont understand how these classes are interface will be used...whether a class in a file checks for presence of class or interface (if it want to use ) first in local file and then check in outside with in the package or any thing else.i am not getting any clarity.If any one understand the trouble what i am facing,i hope will help me.....
// This is InterfaceTest
package Practice;
interface t{
public void h();
public void h1();
}
abstract class InterfaceTest implements t{
public void h(){
}
public void h1(){
}
public abstract void t();
}
//This is other file InterfaceTest1
package Practice;
interface t{
public void h();
public void h2();
}
public class InterfaceTest1 {
}
//This is TestStack file
package Practice;
public class TestStack {
Test t=new Test();
public static void main(String[] args){
TestStack t1=new TestStack();
InterfaceTest it=new InterfaceTest();
}
}
interface t{
public void h3();
}
class Test implements t{
public void h3(){
}
public void h1(){
}
public void h2(){
}
}
class InterfaceTest{
}
These three files used in the same package but i am not getting any errors in name collision

It isn't very clear what you are saying but I'll take a stab at it - leave a comment if I'm not understanding you.
In Java, a class is identified by its fully qualified name. The fully qualified name is .classname.
For example, if a class is in the com.foo.bar package and is named MyClass, the fully qualified name would be com.foo.bar.MyClass. If you have more than one class with the same fully qualified name, you will have a collision and the JVM won't know which class to use. In order to use a class in a different package, you have to import it. You would import the above class with a statement at the top of your java file lie import com.foo.bar.MyClass or, if you wanted to import the entire package, you would use import com.foo.bar.* although that is considered bad practice. Interfaces behave in the same manner. Classes in the same package as a given class do not need to be imported. So, another class in the com.foo.bar package that wishes to use MyClass, would not need to import it.
Does that help you at all? If you can clarify your question, I can try to help you more.
Edit To address your clarification, you can only have one top level, public class per java file. If you wish to define additional public interfaces or classes in a file, they must be nested inside the top-level class. If you use a class and don't fully qualify it, the compiler will first look for a nested class with that name and then look for a class in the same package with that name. If it still can't find it, and you haven't imported it, then it will fail with a class resolution error.
Edit 2 Ah I think I understand. Are you attempting to use those classes in a different class? The compiler won't complain until it attempts to resolve the class that has a name collision. If that class isn't referenced anywhere, the compiler won't care. If you have two MyClass classes, but neither is used anywhere, then the compiler won't bother trying to resolve the class and won't notice the collision. Yes, inside of MyClass if you attempt to reference MyClass it's going to assume that you are referring to the class you are in.
Edit 3 One last try, if you have MyClass and then have another class nested inside it, MyClass1, the fully qualified name for MyClass1 is com.foo.bar.MyClass$MyClass1 because it is nested as part of MyClass

Interface and class names within a package have to be unique:
package foo;
public interface Bar
{
void print();
}
class Bat implements Bar
{
public void print() { System.out.println("Hi there"); }
}
You can have duplicate interface or class names if the packages are different. Fully-resolved class names must be unique.
package other;
public class Bat
{
public void doSomething()
{
System.out.println("And now for something completely different");
}
}
UPDATE:
The example code you present is preposterous. Bad naming conventions aside, you have interface t defined in two separate files. What made you think that you needed to copy and paste it into the second file once you had the first one? Remove interface t from the file containing the definition for InterfaceTest1.
All these are in the same package Practice. What makes you continue to define interface t again and again and again? You also have it in that TestStack definition. Please, think of some unique names if the definitions are indeed unique and your problem goes away.

Related

Import package and how to use all classes in a java file

I am creating a package com.XXXX
Inside that I am declaring many classes in a java file (default - not public)
let is be like:
class A{}
class B{}
class C{}
I am importing com.XXXX in another file
I am unable to use these classes that are inside the package, as they are not public.
So I am pushing to a state of creating individual files for each classes.
Every class is just a small structure, where it doesn't have any extra function. So I thought of keeping them in single file. So I can't declare classes as public
Is there any way to use all classes without splitting them into separate files?
If (somehow) it makes sense to group these classes together, then you could put them inside a wrapper class as static inner classes, for example:
package com.somewhere;
public class Utils {
public static class DateUtils {
public static Date today() {
return new Date();
}
}
public static class FilenameUtils {
public static String stripExtension(String path) {
return path.substring(0, path.lastIndexOf("."));
}
}
}
Then, you will be able to import these elsewhere:
package com.elsewhere;
import com.somewhere.Utils;
public class Task {
Date today = Utils.DateUtils.today();
}
This is because the default java access modifier is package private. When you create the classes without an access modifier they become accessible only within the package.
If you don't want to expose it outside the jar then rename your package to be com.internal.XXXX. When you put the internal keyword that package wont be available outside the jar even thought your classes inside the package would be public.
If you want to have more than one class in the same file, you can use Nested Classes.
Please, take a look at:
https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Example:
class OuterClass {
...
class NestedClass {
...
}
}
You can then refeer to OuterClass.NestedClass from another package

How to reference Java Object classes in separate folders

I have a Main class. I also have another class I have made (call it the "Runner" class). I would like to, however, have more Runner classes (the difference between them being modifications to each respective Runner class by other people). Would it be possible to have each Runner class in separate folders and have the folders in the same directory as the Main class, and then reference the Runner objects in the Main class as if they were a class in the same directory as the Main class?
Yes, this question strikes me like you're viewing Java like php or ruby, etc which isn't quite accurate. With Java, each class has what's called a "Fully Qualified Name" which is derived from the folder it's stored in (like Python). Because Java is compiled, you tell the compiler where to find the code needed to compile a java file, rather than putting a reference to those needed files in the top of the file (like a require statement in php) which would be an instruction to the interpreter.
Say for instance you had a structure like this:
src/
Main.java
/runner1
SomeRunner.java
/runner2
SomeOtherRunner.java
Main.java
public class Main{
public static void main(String[] args){
//use SomeRunner
runner1.SomeRunner.run();
//use SomeOtherRunner
runner2.SomeOtherRunner.run();
}
}
SomeRunner.java
package runner1;
public class SomeRunner{
public void run(){ ... }
}
SomeOtherRunner.java
package runner2;
public class SomeOtherRunner{
public void run(){ ... }
}
Alternatively, you can use imports:
Main.java
import runner1.SomeRunner;
import runner2.SomeOtherRunner;
public class Main{
public static void main(String[] args){
//use SomeRunner
SomeRunner.run();
//use SomeOtherRunner
SomeOtherRunner.run();
}
}
In this example, I chose arbitrary package names (runner1 and runner) which is technically fine. However, best practices state that your package names should be the reverse domain name of your project (i.e. com.myproject) to avoid collisions with other libraries etc. You can read more about that here. When you compile your Main class, you will need to supply the SomeRunner and SomeOtherRunner files to the compiler so it knows where to find them.

Strange behaviour extending abstract class (exercise)

I'm studying for Java SE 7 certification exam and I'm doing some boring excercises about inheritance and access modifiers.
But now I'm getting an unexpected behavior applying inheritance. In my base package com.testpkg I have an abstract class:
package com.testpkg;
public abstract class Abstract {
public int test();
}
NOTE that I voluntarily omitted the abstract modifier for the test() method.
Then I have a concrete class extending Abstract in package com.testpkg.sub:
package com.testpkg.sub;
public class Concrete extends Abstract {
public int test() {
return 0;
}
}
I test this classes using:
package com.testpkg;
import com.testpkg.sub.Concrete;
public class TestMain {
public static void main(String[] args) {
Abstract c = new Concrete();
System.out.println(c.test());
}
}
If I try to compile this, I obviously get two errors:
The method test() requires a body instead of a semicolon
But if I run test class: 0 is printed on console!
This seems very strange to me. Can you explain why the code is working even test() is wrongly declared in Abstract class?
NOTE I'm using Eclipse IDE to compile/run my code.
You need an abstract qualifier on your test() method. You're likely running an old class file. If you change the value of your return statement to something besides 0, you will see that it isn't running this code.
Eclipse allows you to run "half baked" code. The reason why it runs fine here is because, at runtime, you never really depend on the specifics of the Abstract class so it doesn't really matter if you have this type of compile error in it.
Yours class Abstract has compilation errors, because non abstract method should be defined, so it should have a body. abstract qualifier is optional only in case of interfaces.

Java Extending class containing main method

I have the following code as part of an assignment
class Base {
public static void main(String[] args){
System.out.println("Hello World");
}
}
public class Factorial extends Base{
}
My task is run the code and then explain the output.The name of the file is Factorial.java. The code runs without problem and Hello World is printed which to me is surprising. Before typing the code, I was thinking that it wont compile because the parent class, which is being extended should be in another file but now I am not so sure. Would appreciate soome clarification.
Java allows you to define multiple classes within a single .java file with the condition that you can have at most one public class and if you do then the name of that public class must match the name of the .java file. In your case, the class declared public is Factorial and hence your file name has to be Factorial.java.
The inheritance is working as usual here and the public static void main() is inherited by Factorial which is why you see your output on executing java Factorial.
You can have more than one class in the same file, but only one public , as Base isn't a public class, but it's not a recommended practice.

What if main method is inside "non public class" of java file?

I have a java file containing more than one class, out of which one is public. If main method is inside a non-public class. I can't run that java file. Why is that? and there is no compilation error as well. If so, how can I use that main method?
Actually you can execute the main method in a non-public class. if you put this class
class A {
public static void main(String... args) {
System.out.println("This is not a public class!");
}
}
in a file named NonPubClass.java. You can compile this file using javac command but you will not get a NonPubClass.class, you will get a A.class instead. Use java a to invoke that class and you will see the printed string --- This is not a public class!
Have a look at this code:
Super.java
public class Super{ }
class Sub{
public static void main(String[] s){
System.out.println("Hello");
}
}
In order to print Hello you can compile and run the program as:
How this works?
The compiler generates separate .class file for every class in your program. So, instead of calling the main() of non-public class from the public class's main() you can print the output as shown above.
Note: As the convention says, you must put a public class in separate file <class_name>.java. And do not put more than one class in a single file (except if they are inner class) because if you would like to import them or use them with other classes then it will cause problem.
there is something i would like to add although everybody here believes that a public is necessary for the main in a class and that it won't work without main
you can have as many mains in a class as you desire, and you can have them without a public access modifier.
but be careful, only that class which is named after the file can be public
what i mean is if you name your file a.java , then only the class with name a can be public, none other can have this facility
here is a code to show this :
as you can see the name of the file is helping.java
//:initialization/helping.java
class b{
public static void main(){
System.out.println("hello its b");
}
}
class helping {
static void f(float i, Character... c) {
System.out.println("first");
}
static void f(char a, Character... args) {
System.out.println("second");
}
public static void main(String[] args) {
f(1,'a');
f('a','b');
c.main();
}
}
class c{
public static void main(){
System.out.println("hello its b");
}
}
//:~
/*
* output:
* first
* second
* hello its b
* */
Simple Answer. You can't. You need to have main method in a public class and its signature should be public static void main(String... args)
there is no compilation error
Why there would be? You are doing nothing wrong as far as compilation rules are concerned.
Only thing is that your non-public-class-main-method won't work as an entry point of your code.
It is a compile-time error if a top level type declaration contains any one of the following access modifiers: protected, private, or static.This link may be helpful.
It's not a compile time error as u mentioned that top level type declaration shouldn't be protected, static or private.
If u go through the link http://docs.oracle.com/javase/specs/jls/se7/html/jls-7.html#jls-7.6 well that u have shared ,then it's quite clear there that a top-level type declaration refers to only "top level Class and Interface type declarations" and these should not be protected, static or private at top level declarations, but we can use protected, static or private for any methods or variable declaration inside them.
With respect to above code, there is nothing wrong in declaration, and the code will compile and run successfully as all outer top level class are default and there is no violation.
The answer to the question asked at top is exactly as mentioned by few experts at top, that
"for sure we can have a file with main method inside non-public class and it will compile as well as run successfully, but make sure that at the time of running the program we have to pass the class name of "main method" to the java interpreter instead of the class which is public."
If we have 2 classes A(public) and B(non-public containing main method) , then the file will compile with "javac A.java" but while running the code we need to pass the command as "java B" .
You can certainly override main method and it does not violate any compiler rules and hence you will not have any compiler errors.
You check that inspite of the fact that you have more than one class a file that is declared as public is the name of the file you are trying to execute.
This is a convention that the file should be named after the same class which is public in that code.
Hence when you try to execute that class it does not have a main method from which it starts execution.So if you want to execute the main method in the non public class the only way to this is call that main from a main method of the public class.

Categories

Resources