Java allows to define the following pair of classes.
class Class1 { ... }
public Class2 { public Class2(Class1 c1) { ... } }
Why Class2 has public constructor if I cannot instantiate it because Class1 is not accessible?
For the record, there are no public classes that inherit from Class1.
Class1 and Class2 are defined in same package. So they can be accessible. Class1 has default access modifier, which is visible to all Classes inside the same package
At the first glance, it seems like it does not make sense: A user of this package may access Class2. But he can't create an instance of Class2, because he has no access to Class1. So there is no reason of making the constructor public, when the argument that it needs is not public as well.
The only situation where this actually makes sense is when there is another public class in the same package that extends Class1. Then you could create an instance of this class, and pass it to the constructor:
// Assuming this class extends Class1, and it is public, you
// can create an instance of this class from outside the package:
ExtendedClass1 e = new ExtendedClass1();
// This is using the public constructor that expects a Class1.
// Although Class1 itself is NOT public, this constructor
// can be called with an instance of a (public) class that
// extends Class1
Class2 c = new Class2(e);
But since the latter was excluded in the question, there is no reason to have this public constructor.
It is reasonable to have a class that limits its creation/access to members of the same package with a view that other classes in the same package will extend this class and be made public.
For example if you were implementing the Template pattern you might have super class (probably abstract) that implemented the base, shared, logic, with one or more concrete classes that implemented the the differing steps.
These concrete classes could then be instantiated by callers, but the base class wouldn't.
Arguably though the base class could equally be protected instead of package scope.
Every class has a default constructor(if you do not provide one) you can do :
Class1 c1 = new Class1();
then
Class2 c2 = new Class2(c1);
Related
How can i call an non static method of Abstract class, without using its sub class or extends it because abstract class and sub class is too complex so i do not want to cause any side effect.
for example concrete static methods of an abstract class can be call with class name an dot operator, without creating sub class. Similar is there any way to call a non static method.
i just want to run a method and i do not want run any other code. i tried to use reflection but it requires instance
Abstract classes are abstract, meaning that you cannot create an instance of the class.
Therefore, you cannot call instance methods of an abstract class.
public abstract class Foo {
static void bar();
void foobar();
}
you can call Foo.bar() as it is not an instance method (meaning that it does not require an instance of the class) but you cannot call foobar() since you cannot do new Foo().foobar().
Foo.bar(); // OK, we don't need an instance.
Foo foo = new Foo(); // Not OK - we cannot instantiate an abstract class.
foo.foobar();
For a way to create an instance of an abstract class without having to use derived classes, see ernest_k's answer utilizing anonymous classes.
The short answer is that you can't. You need an instance.
An easy way to create an instance is using an anonymous class:
AbstractClass o = new AbstractClass(){
//implement abstract methods... or just leave stubs
};
o.concreteMethod();
According to this document, and many similar documents, a concrete class is described as:
A concrete class in Java is any such class which has implementation of all of its inherited members either from interface or abstract class
And can used like this:
public abstract class A {
public abstract void methodA();
}
interface B {
public void printB();
}
public class C extends A implements B {
public void methodA() {
System.out.print("I am abstract implementation");
}
public void printB() {
System.out.print("I am interface implementation");
}
}
In the above example class C is a concrete class.
Is this the only way to create a concrete class. Can you give me more info about concrete class?
A concrete class is a class that has an implementation for all of its methods that were inherited from abstract or implemented via interfaces. It also does not define any abstract methods of its own. This means that an instance of the class can be created/allocated with the new keyword without having to implement any methods first. Therefore it can be inferred that any class that is not an abstract class or interface is a concrete class.
In your code above, C will be a concrete class as it implements all abstract methods inherited from A and implemented from B. Also, it does not define any abstract methods of its own.
The simplest definition of a concrete class is that it's a class that is not abstract.
As per name suggests, concrete means Solid, it means having no any row part or unimplemented things(methods).So we can conclude that concrete classes are those classes that can be instantiated with new key word.
MyClass myClass = new MyClass();
1.concrete class is a class which can never become
an abstract or interface .It can extend or implement or both.
2.The class is said to be concrete if all its methods and variables has defined.
A concrete class in Java is any such class which has implementation of all of its inherited members either from interface or abstract class
In the above program, representing abstract as public class will sometimes show some compile time errors to define that in its own file. As simple, just avoid using public keyword or modifier while using abstract class in your program to avoid some uncertainty. Any method that is invoked using new keyword (object creation) other than abstract and interface classes is called as concrete class.
I just came across two distinct opinions regarding abstract class :
1) One says , abstract method cannot be used in concrete(general) class ; while the abstract classes can have both abstract/non-abstract methods
2) While , a tutorial that has been highly watched on youtube says , " Any class that has an abstract method , will let its class be automatically defined as abstract "
2nd point is totally in contrast to the 1st point ; While implementing it , I did succeed only in the 1st concept and not 2nd though . But , still I want to have a detailed clarity in this regard , if anyone can help me with patience .
As described in the official Java tutorial, "If a class includes abstract methods, then the class itself must be declared abstract". It does not automatically become abstract; it needs to be marked as abstract explicitly.
Any class that contains abstract methods cannot be instantiated because it contains methods that are undefined. Any time an object of a class is created, it must contain all contents of the class and they must all be defined.
So you need to declare the class as abstract which means that the class cannot be instantiated. But just because a class is abstract, doesn't mean it must implement only abstract methods. For example, you can have a static method in an abstract class because calling a static method belongs to the class rather than an object or instance of the class.
An abstract class can have methods abstracts and non abstract. For exemple,
public abstract class Employee {
...
//this method would be implemented in those classes that extends from Employee.
public abstract void calculateSalary();
public Employee addEmployee() {
//Method body
}
But if you declare an abstract method in a non abstract class this has to be converted itself into am abstract one.
On the other hand abstract methods will be implemented in the inherited classes of an abstract parent class. So you would be doing this implementation in a generic class.
I hope this would helps.
Why can you create a child class in Java whose visibility is less than the super class.
package 1
public class Class1 {
public Class1 hello(){
Class1 c= new Class2();
return c;
}
}
class Class2 extends Class1 {
public Class1 hello() {
System.out.println("In overriden method");
return null;
}
}
Say both Class1 and Class2 are in the same package , Class2 visibility is package private.
package 2
public class Major {
public static void main(String[] args) {
Class1 ob = new Class1();
ob.hello().hello();
}
}
You will notice that the "In overriden method" will be printed because of runtime polymorphism.
During runtime how can hello() method of Class2 be accessed from main() when Class2 is in a different package with package-private visibility ?
Class2 should not be accessible and as such the hello() method in Class2 should also not be accessible.
The protected keyword (somehow similar to package private) is a way to protect your code from being used externally, and this is exactly what happens in your example. You are not using Class2 directly, you are using Class1 which grants you the right to use the protected Class2 indirectly.
This is a responsibility principle. public Class1 takes the responsibility to grant external packages the usage of protected Class2. But this responsibility also means that the developer of Class1 has to know why and how he grants you that right.
The fact that you extend Class1 has no real meaning in your example, and your confusion may come from this. You can't instantiate Class2 from outside your package, but Class1 can.
Actually, given the type signatures of the methods involved, it probably couldn't work any other way.
Class1 declares a method called hello returning an object of Class1. So, what gets returned from that method must implement a compatible interface to Class1. When Class1.hello() returns an instance of Class2 there shouldn't be any way in which the caller can interact with it differently than if it was an instance of Class1 - this is the Liskov Substitution Principle in action - one of the key object-oriented principles.
If Class2.hello() became innaccessible by virtue of Class2 being hidden then the caller would have to contend with the fact that they don't know what type of object will be returned by Class1.hello() - sometimes it might be an object of Class2 and sometimes it might be an object of Class1, or any other object which could extend from Class1 and the only way of knowing would be to examine the code - i.e. knowing Class1's implementation details. The compiler wouldn't be able to guarantee type safety in that kind of situation, because Class1.hello() could, in principle, be undecidable or dependent on runtime state. In a statically typed language that's pretty much game over.
Making a class hidden in some way - by creating it as a private type, by implementing an interface anonymously, through reflective-trickery, etc - is only supposed to make the type itself hidden and not the interface which it implements. By extending another class any given type automatically inherits the parent type's interface, including its visibility. Extending types are only allowed to increase an interface's visibility, not to decrease it, otherwise the Liskov Substitution Principle is violated.
I'm trying to use extends (inheritance) in Java. I made a quick abstract class to extend from, and then extended it. However my IDE now is saying that "An enclosing instance that contains abstract_class is required" and gives my constructor for the derived classes big error lines. What on earth is it going on about? The abstract class doesn't have or need any sort of constructor.
Just for reference, I'm using extends rather than implements in part because the implementation details that I don't want to have to maintain for every derived class which are identical involve using reflection on this.
Edit: I've read some of the responses. What in God's name is a static (or non-static, for that matter) class? And just to irritate all of you, it didn't solve the problem.
// some_class.java
public class some_class {
public static abstract class abstract_class {
...
}
...
}
// Model.java
public class Model extends some_class.abstract_class {
public Model(...) {
// No enclosing instance! Critical error.
...
}
...
}
And I thought that C++'s header files were bad.
The code you posted seems to compile just fine for me. Try doing a clean build in your IDE and it should work.
Just for your own curiosity, Java has 2 types of inner classes: static and regular or (non-static). If you don't include the static keyword for an inner class definition, it means that an instance of that class will always require an instance of the parent class. For ex:
public class MyClassOuter {
//...
public class MyClassInner {
//..
}
}
If you write that, it is understood that any instance of MyClassInner will have an implicit reference to an instance of MyClassOuter.
Static, on the other, hand implies no such thing. It is just a class definition that happens to be inside another class definition. The outer class is used almost like a package (though not quite).
if you have
interface MyInterface
{
abstract class MyAbstractClass {
// ...
}
}
and then you try
class ConcreteClass extends MyAbstractClass {
}
You will get the error described. The fix is to either move MyAbstractClass to a top-level class (put it in it's own file - not strictly necessary for non-public classes, but keeps the code organized.) Alternatively, add the static modifier to the MyAbstractClass declaration.
The "enclosing instance" message almost certainly implies that you have a (non-static) inner class for your superclass. In most cases, inner classes can and should be static - that's likely the best workaround here. Alternatively, as the message says, you will need to use an enclosing instance of the "outer" class, if your parent really makes sense as a non-static inner class.
Posting some code will help disambiguate between these causes and suggest the best way to resolve it. I'll also be able to give examples of the resolutions with the right class names - currently I don't think arbitrary names will help that much as it sounds like you hadn't identified the inner/outer class issue.
You need to in your child class add in the constructor super() that super class can be created.
class A{
.
.
.
class B{
. . .
}
}
if you want to access the Class B and it it is not static inner class you can write the code as
A.B objOfB = new A(). new B();