creating an interface and implement it in another package - java

Create an interface containing three methods, in its own package.
Implement the interface in a different package. Prove that all the
methods in an interface are automatically public.
This is the question above which I have got as an assignment, and I am allowed to get help from anywhere.
What I have tried is:
file 01: Student.java
package student;
public interface Students
{
void RollNo();
void course();
void marks();
}
file 02: MyMain.java
import student.*;
class Test1 implements Students
{
void RollNo()
{
System.out.println("18CS35");
}
void course()
{
System.out.println("OOP");
}
void marks()
{
System.out.println("85");
}
}
class MyMain
{
public static void main(String[] args)
{
Test1 t = new Test1();
t.RollNo();
t.course();
t.marks();
}
}
What I did is, compiled File 01 and created a package (folder in same direcotry)
When I compile file 02, I get this error.
MyMain.java:2: error: cannot access Students class Test1 implements Students
^ bad class file: .\Students.class
class file contains wrong class: student.Students
Please remove or make sure it appears in the correct subdirectory of the classpath.
Commands I am using to compile:
javac –d . Student.java
javac Student.java
javac MyMain.java

Declare the interface in the student package:
package student;
public interface Student {
void rollNo();
void course();
void marks();
}
then in another package, declare your MyMain class
package anotherpackage;
import student.Student;
public class MyMain {
public static void main(String[] args) {
Test1 t = new Test1();
t.rollNo();
t.course();
t.marks();
}
}
class Test1 implements Student {
#Override
public void rollNo() {
System.out.println("18CS35");
}
#Override
public void course() {
System.out.println("OOP");
}
#Override
public void marks() {
System.out.println("85");
}
}
The file is called MyMain.java and the MyMain class must be declared public inside it. This is important. You must have one and only one public class in the file with the same name as the file.
Test1 on the other hand is not declared public.
You don't have to add the #Override annotations, but it is good practice to always add them when you implement or override a method;
To get it to work:
stick Student.java in a directory called student
stick MyMain.java in a directory called anotherpackage
then compile
javac student/Student.java
javac anotherpackage/MyMain.java
and run:
java anotherpackage/MyMain
outputs:
18CS35
OOP
85
The proof:
Note that when you implement your methods, you need to declare them public, otherwise the compiler will complain that you reduce their visibility. That proves that they are considered public in the interface.

Your interface's methods are public by default (interface methods are always publich). Your implementation's methods have default visibility. An implementation can't have a lower visibility than the interface or abstract method it's implementing.
Just declare your methods in the Student-class public.

Based on the commands you're using to compile the code, it looks like you've put both Students.java and MyMain.java in the same directory. Since Students is supposed to be in a package named student, your directory structure should be like below, because Java looks for the .class files in directories according to the package names.
student/
Students.java
Students.class
MyMain.java
MyMain.class
Or if you have separate source and build directories:
src/
student/
Students.java
MyMain.java
build/
student/
Students.class
MyMain.class
All of this should be handled automatically if you use an IDE like Eclipse, Netbeans or IntelliJ IDEA.

Related

i'm getting compile time-error when i create class public why?

public class foo{int a;}
public class foo2{public static void main(String[] a){System.out.println("love");}}
The error is:
C:\Users\PUSHPAM\Desktop\java>javac foo2.java foo2.java:1: error: class foo is public, should be declared in a file named foo.java public class foo{
You can only have one public class per Java source file. The name of that file must match the public class name, so if you have a public class called MyClass, it must be in a file called MyClass.java.
Suppose if you have multiple classes in single program then you have to save your class with the class which have main() method. And that class should be public type. Don't make all the classes as public in one file.
Example:
class Vehicle {
//something
}
class Audi {
//something
}
class Manager {
public static void main(String[] args)
{
// something
}
}
main() method is available in Class Manager. Because of this i have to save the file with Manager.java.
javac Manager.java ---- .class files will generate for all the classes
java Manager --- getting output

Confusion with Java packages

So I thought I understood packages, but turns out I don't.
Classes inside a package: I have this folder structure: mypackage/mysubpackage. Inside mysubpackage folder I have 2 classes:
package mypackage.mysubpackage;
public class Class1 {...}
and
package mypackage.mysubpackage;
public class Class2 {...}
However, when I compile Class1 (which uses methods from Class2) using javac Class1.java inside the directory mypackage/mysubpackage, it can't see Class2:
Class1.java: error: cannot find symbol
Class2 c = new Class2();
^
symbol: class Class2
location: class Class1
It works fine if I run javac Class1.java in the directory that contains mypackage/mysubpackage. Shouldn't the compilation work inside mysubpackage folder?
Classes in another package: Now, I have another class with methods that I want to be accesible to all the subpackages, so I create a final Commons.java inside mypackage/commons:
package mypackage.commons;
public final class Commons {
public static double method() {...}
...
}
And then I update Class2 importing that class so that I can use its methods inside the class:
package mypackage.mysubpackage;
import mypackage.commons.*;
public class Class2 {...}
Now it doesn't find the method I defined in the final class:
./mypackage/mysubpackage/Class2.java: error: cannot find symbol
double var = method();
^
symbol: method method()
location: class Class2
Shouldn't if find it? I think I'm importing it correctly, the methods are static and the class is final. Why doesn't it recognize it?
Cheers!
Looks like your problem is with where you set your working directory when you launch the Java compiler from the command line.
I would recommend that you pick up an integrated development environment -- Eclipse is a good one. Using the IDE you run into no such problems. Here are the classes I just created in Eclipse, which compile correclty.
Commons
package com.example.packagecommons;
public class Commons {
public static double method() {
return 0;}
}
Class1
package com.example.packages;
public class Class1 {
private Class2 c2;
public Class1() {
c2 = new Class2();
}
}
Class2
package com.example.packages;
import com.example.packagecommons.Commons;
public class Class2 {
private double initialValue;
public Class2() {
initialValue = Commons.method();
}
public double getValue() {
return initialValue;
}
}
Suppose your two classes Demo01 and Demo03 are in package pack1.subpack and your Demo02 is in pack2
So the hierarchy is like
someDrive/pack1/subpack/Demo01
someDrive/pack1/subpack/Demo03
someDrive/pack2/Demo02
someDrive/pack1/common/Demo04
where Demo01 is
package pack1.subpack;
import pack2.Demo02; // need to add this if calling class of different package
import pack1.common.Demo04; // if you are going to use Demo04 class in Demo01 class
public class Demo01 {
public void run() {
System.out.println("--running Demo01-");
}
public static void main(String[] args){
Demo01 demo01 = new Demo01();
demo01.run();
Demo02 demo02 = new Demo02();
demo02.run();
Demo03 demo03 = new Demo03();
demo03.run();
Demo04.run();
}
}
Demo02 is
package pack2;
public class Demo02 {
public void run() {
System.out.println("--running Demo02--");
}
}
Demo03 is
package pack1.subpack;
public class Demo03 {
public void run() {
System.out.println("--running Demo03--");
}
}
Demo04 is
package pack1.common;
public final class Demo04 {
public void run() {
System.out.println("--running Demo04--");
}
}
Then just compile it using javac pack1/subpack/Demo01.java
and execute it using java pack1/subpack.Demo01
I know this thread is old but I'd like to clarify things so as to help future viewers.
Your first question basically is, how does the Java run-time system know where to look for packages that you create? Remember these 3 rules (one of them must apply):
Your main package must be in a subdirectory of the current working directory to be found.
You can specify a directory path or paths by setting the CLASSPATH environmental variable.
You can use the -classpath option with java and javac to specify the path to your classes when you are executing your code via the terminal/cmd.
To answer your first question, you are executing your code from mypackage/mysubpackage. For Java run-time to recognise Class2, you must execute from mypackage.
Coming to the second question, when you import all the contents of a package using *, you need to refer to static class members by explicitly writing the class name before them, as Java does not know which class in the package you are referring to. Hence, in your code, you must write
Commons.method() instead of just method(). If you do not want to prefix the name of the class time and again, you can explicitly import the specific class you want. In your case, this would be mypackage.commons.Commons. Then you can call method() directly (provided it is static).
sh$ cd package/subpackage
sh$ javac Class1.java
Will lead to an error as the compiler will try to locate Class2 in the package/subpackage subdirectory of the current directory.
You have to compile that way:
sh$ javac package/subpackage/Class1.java
Here is a complete working example:
sh$ cat pkg/subpackage/Class1.java
package pkg.subpackage;
import pkg.commons.Class2;
public class Class1 {
public static void main(String args[]) {
Class2.doSomething();
}
}
sh$ cat pkg/commons/Class2.java
package pkg.commons;
public class Class2 {
public static void doSomething() {
System.out.println("hello");
}
}
sh$ javac pkg/subpackage/Class1.java
sh$ java pkg.subpackage.Class1
hello

Accessing a class inside a non-existing class

How does this work?
EDIT: Being static is not a good explanation, because I can use non-static methods and it will all work. Updated the code to reflect that.
I have this in a file called Foo.java:
// This is in the Foo.java file
class Test {
public void printSomething() {
System.out.println("In Foo.Test");
}
};
and this in a file called Caller.java:
// This goes in the Caller.java file
public class Caller {
public static void main(String[] args) {
Test test = new Test();
test.printSomething();
}
}
I can execute my Caller and it will print In Foo.Test. How can this not be a compilation problem? I don't even have a Foo class created. I don't even have to define Foo.Test in the Caller.
This is on Eclipse Luna, Java8.
Java is weird like that. You could have a file without any lines of code and it would still compile. Go on try it.
Now, I think you are confusing Test with Foo.Test (I understand, it's Friday).
Intrinsically what you defined is this:
public class Foo {} // this is by default, but don't try to use it because you didn't define the scope
class Test {}
And your perplexity is "OMG, Test is the impure offspring of a non-existing class!!!", because you were expecting something like
public class Foo {
class Test {}
}
This has nothing to do with a method being static. It is about quirkiness in the javac.
Happy Friday everyone! Time for happy hour.
The main-Method of the Foo.java is declared static
calling static methods works without creating a object of the class.
E.g you can create following Method in Foo.java
class Test {
public static void test(String test) {
System.out.println(test);
}
};
Now you can call Test.test("No object will be created"); and there will be NO instance of Test
A java file could contain single public class, but it could have as much non-public classes (package-local in your case) as you wanted.
Foo.Test is for inner classes. The one you declared is top level type.

I Have a problem with understanding some Java code

The Code:
package com.keyoti.rapidSpell;
import java.util.Comparator;
// Referenced classes of package com.keyoti.rapidSpell:
// RapidSpellChecker
class RapidSpellChecker$CompareL
implements Comparator
{
public int compare(Object a, Object b)
{
return (int)(100D * (suggestionScore2b(topWord, (String)b) - suggestionScore2b(topWord, (String)a)));
}
public void with(String w)
{
topWord = w;
}
private String topWord;
RapidSpellChecker$CompareL()
{
}
}
This is the one the many classes in the application.
What does the $ sign in class RapidSpellChecker$CompareL implements Comparator signify?Is it simply the class name or has some significance?
I suspect this is decompiled code. (See at the bottom for more information.) The $ shows that it's a nested class within RapidSpellChecker. So the code would originally have looked something like this:
public class RapidSpellChecker
{
// Other code withing RapidSpellChecker
static class CompareL implements Comparator
{
// Code for compare, with etc
}
}
I've shown this as a static nested class, because the code you've shown doesn't have any implicit reference to an instance of RapidSpellChecker. If it did, the original code would have been like this:
public class RapidSpellChecker
{
// Other code withing RapidSpellChecker
class CompareL implements Comparator
{
// Code for compare, with etc
}
}
In this case it's an inner class.
See the Java tutorial on nested classes for more information.
EDIT: I originally thought this was invalid code; that you couldn't use $ in an identifier in Java to start with. It turns out I'm wrong. From the Java Language Specification, section 3.8:
The $ character should be used only in mechanically generated source code or, rarely, to access preexisting names on legacy systems.
So it's valid, just discouraged.
That's a nested class. When the Java compiler compiles a class with nested classes, it separates all of them in different .class files.
class A {
class B {
}
}
gives A.class and A$B.class
You can use $ in a variable name if you want. In a variable name it has no special significance.
$ is also typically used to indicate inner classes when you compile using javac
If you compile
class A {
class B {
}
}
You'll see A.class created and B.class.
For fun and amusement, you could create confusing looking "JQuery"-esque code in Java (you need the static import to use the $ static method). See the example below:
import static thisPackage.*;
public class $ {
public static $ $(String s) { return new $(s); }
public $ fadeIn(int fade) { return this; }
public $ slideUp(int slide) { return this; }
public $ delay(int ms) { return this; }
public $(String s) { }
public static void main(String[] args) {
$("#foo").slideUp(300).delay(800).fadeIn(400);
}
}
Implementing this with a DOM library underneath would be a fun project!

Accessing non top-level class without a top level class in Java

I have a Java file TestThis.java like the following:
class A
{
public void foo()
{
System.out.println("Executing foo");
}
}
class B
{
public void bar()
{
System.out.println("Executing bar");
}
}
The above code file is compiling fine without any warnings/errors. Is there any way I could access any of class A or B without a top level class from any other external class?
If no then why does Java even permit compiling of such files without a top-level class?
As usual (for example, accessing from the Test.java):
public class Test {
public static void main(String... args) {
A a = new A();
a.foo();
B b = new B();
b.bar();
}
}
The rule here is that you could not have more than one public class in the source file. If you have one, the filename must match this public class name. Otherwise (your case), you can name your file as you wish. Other, non-public classes, will be package-visible and you can access them as usual.
Any other class in the same package can access A and B; in this case the null package is being used since no package statement is present for the source file.

Categories