make class only instantiable from specific class - java

Let's say I have 3 classes
class1, class2 and class3.
How can I have it that class1 can only get instantiated by class2 (class1 object = new class1()) but not by class3 or any other class?
I think it should work with modifiers but I am not sure.

I want to rename your classes to Friend, Shy and Stranger. The Friend should be able to create Shy, but Stranger should not be able to.
This code will compile:
package com.sandbox;
public class Friend {
public void createShy() {
Shy shy = new Shy();
}
private static class Shy {
}
}
But this code won't:
package com.sandbox;
public class Stranger {
public void createShy() {
Friend.Shy shy = new Friend.Shy();
}
}
In addition, if we create a new class called FriendsChild, this won't compile either:
package com.sandbox;
public class FriendsChild extends Friend {
public void childCreateShy() {
Shy shy = new Shy();
}
}
And this naming convention makes sense when you think about it. Just because I'm a friend of someone doesn't mean my child knows them.
Notice that all these classes are in the same package. As far as I can understand, this is the scenario you're looking for.

Another option besides making the constructor protected:
Make the class1 constructer private
Make a public static factory method that requires a valid instance of class2 inorder to return an instance of class1

Make class1 inner class of class2.

Update
make protected constructor and put the eligible class in same package, if you want any class outside of package to construct this instance then you need that class to extend ClassA in this example,
if you restrict it then go for default access specifier
package com.somthing.a;
public class ClassA {
ClassA() {
super();
// TODO Auto-generated constructor stub
}
}
package com.something.a;
public class ClassB {
public static void main(String[] args) {
new ClassA();//valid
}
}
package com.something.c;
public class ClassC {
public static void main(String[] args) {
new ClassA();// invalid
}
}

Related

Calling a method of abstract class from a concrete class without extending

Example abstract class is bellow.
public abstract class Vehicle {
void maintain(String str) {
System.out.println(str);
}
}
Example concrete class is bellow.
public class Driver {
public static void main(String[] args) {
}
}
Now I need to access the maintain method without extending the Vehicle class.Is there any way to do this without using static content?
No, there isn't, because maintain is an instance method. To call an instance method, you must have an instance. You can't create an instance of an abstract class.
You can subclass it anonymously (see this tutorial), but you still need to subclass it.
You can use an anonymous inner class. I've used your example code but also defined an anstract method in Vehicle
public class AbstractTest {
public static void main(String[] args){
Vehicle v = new Vehicle() {
#Override
void myOtherAbstractMethod() {
// Do what you need here
}
};
v.maintain("foo");
}
public static abstract class Vehicle {
void maintain(String str) {
System.out.println(str);
}
abstract void myOtherAbstractMethod();
}
}
You cannot do that as abstract classes are abstract. Also in your case there's no connection between Driver and Vehicle so even if you would be able to compile that code (you won't), then ClassCastException would show up.
You must extend abstract class first, like it or not.

Can I call instance method of a parent class directly in child class in Java?

I have the below two classes. I'm wondering how I'm able to call the instance method of ClassA i.e. AMessage() in class B with out the instance of a ClassA or ClassB created?
I was thinking I should call instance method of ClassA i.e. AMessage() in class B as below:
new ClassA().AMessage(); //no compile error
new ClassB().Amessage(); //no compile error
Parent Class (ClassA.java)
public class ClassA {
public void AMessage(){
System.out.println("A Message");
}
}
Child Class (ClassB.java)
public class ClassB extends ClassA{
public void BMessage(){
AMessage(); //no compile error
}
public static void main(String[] args){
new ClassB().BMessage();
}
}
When a class extends another class, it automatically inherits the visible fields and methods of the base class. By visible I mean accessible members. Private members are not inherited. Learn more about inheritance in http://www.tutorialspoint.com/java/java_inheritance.htm
So if you have a class ClassA having a method AMessage like this :
public class ClassA{
public void AMessage(){
System.out.println("A message");
}
}
and ClassB which extends ClassA like this :
public class ClassB extends ClassA{
public void BMessage(){
AMessage();
}
public static void main(String[] args){
new ClassB().BMessage();
}
}
ClassB automatically inherits members of ClassA i.e. they act as if they are members of ClassB itself. That's why we can call the instance method of ClassA inside ClassB without any instance, because they belong to ClassB as well. Also besides instance methods, you can call static methods like that as well. (But of course you can not call instance methods inside static methods.)
As an additional answer I would like to suggest that (although it is not related to the question but it is a good practice) you should not name any method of a class (instance or static) starting with a capital letter. It doesn't generate any compiler error if you still name it like that, but it affects the readability. I have written the names like that only to relate to your question.
Use super keyword to call base class methods. Check this for reference -
http://docs.oracle.com/javase/tutorial/java/IandI/super.html
public class ChildClass extends BaseClass{
public static void main(String[] args){
ChildClass obj = new ChildClass();
obj.Message();
}
public void Message(){
super.Message();
}
}
class BaseClass {
public void Message(){
System.out.println("Base Class called");
}
}
Or you can do it like this as well -
public class ChildClass extends BaseClass{
public static void main(String[] args){
new ChildClass().Message();
}
}
class BaseClass {
public void Message(){
System.out.println("Base Class called");
}
}
yes you can call method directly instance method of parent class from child class object provided parent class method should be public
you can call in this way
new ClassB().AMessage();
it will also work

Class(implementing the interface) and interface in same file and accessing the class from a main class in different package

I was going through some design pattern videos on YouTube, however I have a small doubt on some basic Java concept. I tried searching for solution, but was unable to find one. Below is my query.
I have some classes Animal.java, Dog.java, an interface Fly.java which also has a class named CantFly in same file. A main method CheckAnimal.java. Below is the code
Animal.java
package com.classification.pojo;
public class Animal {
public Fly flyingType;
public String tryToFly() {
return flyingType.fly();
}
public void setFlyingAbility(Fly newFlyType) {
flyingType = newFlyType;
}
}
Dog.java
package com.classification.pojo;
public class Dog extends Animal {
public Dog() {
super();
flyingType = new CantFly();
}
public void digHole() {
System.out.println("I am digging hole!");
}
}
Fly.java
package com.designpattern.strategy;
public interface Fly {
String fly();
}
class CantFly implements Fly {
public String fly() {
return "Can't fly";
}
}
class ItFlys implements Fly {
public String fly() {
return "I can fly";
}
}
CheckAnimal.java
package com.designpattern.main;
import com.classification.pojo.Animal;
import com.classification.pojo.Dog;
import com.classification.pojo.Fly;
public class CheckAnimals {
public static void main(String[] args) {
Animal doggy = new Dog();
System.out.println(doggy.tryToFly());
doggy.setFlyingAbility(new ItFlys());
System.out.println(doggy.tryToFly());
}
}
In CheckAnimal.java, for doggy object to invoke setFlyingAbility() method correctly, Animal.java, Dog.java and Fly.java needs to be in same package. If I keep Fly.java in different package, I cannot access CantFly() constructor. I hope I have made my point clear.
-
Ishan
You've declared CantFly without any access modifier:
class CantFly
... which means it's only accessible within the same package. Just make it public, and then you'll be able to use it within other packages. See the Java tutorial on access modifiers for more information. The same is true for the ItFlys class.
Additionally, you haven't imported the right package in your CheckAnimal.java file. You should be importing com.designpattern.strategy.ItFlys. You don't need to import Fly at all in CheckAnimal.java, as you're never referring to that interface directly in that file.
That's right. You can make the CantFly class public to access it outside of it's package, but note that doing that requires you to put it in its own file.
That is: Create CantFly.java with the following content:
package whatever.package.you.want;
import com.designpattern.strategy.Fly;
class CantFly implements Fly {
public String fly() {
return "Can't fly";
}
}
Also, it shouldn't be new Fly.CantFly() (since you haven't defined CantFly inside the Fly interface). It should be just new CantFly().
If you really want to keep Fly and CantFly in the same file, you can let CantFly be an inner class:
interface Fly {
...
class CantFly {
...
}
}
and then instantiate it with new Fly.CantFly(). If you're fine with this, I'd probably recommend you to consider using an enum instead:
enum FlyCapability {
CANT_FLY {
#Override
public String fly() {
return "Can't fly";
}
},
CAN_FLY {
#Override
public String fly() {
return "Can fly";
}
};
public abstract String fly();
}
First Of all Fly is an interface that cannot be instantiate which you are doing in CheckAnimal class.
Try this:-
package com.designpattern.main;
import com.classification.pojo.Animal;
import com.classification.pojo.Dog;
import com.classification.pojo.Fly;
public class CheckAnimals {
public static void main(String[] args) {
Animal doggy = new Dog();
doggy.setFlyingAbility(new CantFly());
}
}
and CantFly is no a method it is a class.
This is because the default modifier of a class is package-private, meaning it is visible only by classes in the same package.
You can simply make CantFly a public class defined in its own Java file.
CantFly is not nested inside the Fly interface, so you would need to call its constructor using new CantFly() instead of new Fly.CantFly().

how do i access a public method of a default class outside the package

I have a class with no modifier(default), which has a public method called mymeth. I know I could access the method when I am within the package. However I would like to access the method when I am outside the package. does anyone has an Idea on how it could be done. theoretically I think it should be possible since public method means access by the world. here is the example of my class and method:
class myclass{
public void mymeth(int i,int b){
.....
}
}
set myclass class to be public.
**FYI, Classes in Java start from upper Case letter
Directly you cannot. 'public' makes everything visible. But if you can't see the class, it's difficult to call anything. However,
You can extend the default class with a public class, eventually myMeth is exposed.
PubClass.java
package p1;
class DefClass{
public void myMeth(){
System.out.println("from myMeth!");
}
}
public class PubClass extends DefClass{
public PubClass(){
super();
}
}
MainClass.java
package p2;
class MainClass {
public static void main(String[] args) {
p1.PubClass pub = new p1.PubClass();
pub.myMeth();
}
}
output:
from myMeth!
A real practical use for this would be, overriding a public known method in that hidden class. You can implement a public method in a hidden class, so the world can call your public method (public implementation rather) without the class being exposed. For example the public method of the Object class is overridden here by DefClass:
PubClass.java
package p1;
class DefClass{
public String toString(){
return "DefClass here. Trying to explain a concept.";
}
}
public class PubClass extends DefClass{
public PubClass(){
super();
}
}
MainClass.java
package p2;
class MainClass {
public static void main(String[] args) {
p1.PubClass pub = new p1.PubClass();
System.out.println(pub.toString());
}
}
output:
DefClass here. Trying to explain a concept.
public interface SomeInterface{
public void mymeth();
}
class MyClass implements SomeInterface{
public void mymeth(){
}
}
//is in the same package as MyClass
public MyClassFactory{
public SomeInterface create(/*parameters*/){
//create instance from parameters
//For your case
MyClass instanceOfAnyClassThatImplementsSomeInterface = new MyClass(/*pass the parameters*/);
return instanceOfAnyClassThatImplementsSomeInterface;
}
}
One of the ways is already defined in answers but If you want to restrict the public access of the class then you can create an interface and access the method through it.
Set myclass as public then put it in the build path of the class you need to use myclass.
In your code, myclass has the default (package-level) access modifier. It should be declared using the public access modifier so that it is accessible outside its package. For details, read more about Controlling Access in Java.
As a side note, the Java standards require you to capitalize each word in the class name, so you should use MyClass. I recommend you the Java Conventions document.
Consider making another public class MyChild with the same package name as MyClass and expose the method from MyChild class
public class MyChild extends MyClass {
public void myTestMethod(){
super.myTestMethod
}
}
Now in your class where you want to use the method, simply use the instance of MyChild class
MyChild m = new MyChild();
m.myTestMethod();
Cheers :)

Why is there a private access modifier in an abstract class in Java, even though we cannot create an instance of an abstract class?

I know it is not a good coding practice to declare a method as private in an abstract class. Even though we cannot create an instance of an abstract class, why is the private access modifier available within an abstract class, and what is the scope of it within an abstract class? In which scenario is the private access specifier used in an abstract class?
check out this code where Vehicle class is abstract and Car extends Vehicle.
package com.vehicle;
abstract class Vehicle {
// What is the scope of the private access modifier within an abstract class, even though method below cannot be accessed??
private void onLights(){
System.out.println("Switch on Lights");
}
public void startEngine(){
System.out.println("Start Engine");
}
}
Within is the same package creating a Car class
package com.vehicle;
/*
* Car class extends the abstract class Vehicle
*/
public class Car extends Vehicle {
public static void main(String args[]){
Car c = new Car();
c.startEngine();
// Only startEngine() can be accessed
}
}
Since an abstract class can contain functionality (as opposed to an interface) it can have private variables or methods.
In your example you might do something like
public void startEngine(){
injectFuel();
igniteSpark();
// etc. my understanding of engines is limited at best
System.out.println("Start Engine");
}
private void injectFuel() {}
private void igniteSpark() {}
That way you can spread some of the work to other methods (so you don't have a 1000 line startEngine method), but you don't want the children to be able to call injectFuel separately since it doesn't make sense outside the context of startEngine (you want to make sure it's only used there).
Or even more you might have a private method that gets called in several other public methods, with different parameters. This way you avoid writing the same code twice or more in each of the public methods, and grouping the common code in a private method makes sure the children don't access it (like they couldn't just call part of the public method before). Something like this:
public void startEngine() {
dishargeBattery(50);
System.out.println("Start Engine");
}
public void startRadio() {
dischargeBattery(20);
}
private void dischargeBattery(int value) {
battery.energy -= value; //battery should probably be a private field.
}
This way your methods can have access to the battery, but the children shouldn't mess with it, and you don't write the same line (battery.energy -= value) in both of them. Take note though, that these are very simple examples, but if dischargeBattery was a 500 line method, writing it in both the other methods would be a hassle.
It's the same as in a non-abstract class, there's no difference.
Which means that if nothing in your abstract class calls the private method, then you can just as well remove it, as it won't be called (baring some evil reflection work).
Usually, private methods are only used as internal utility methods that have a very specific task that the other methods in the class use to do their work.
I know it is not a good coding
practice to declare a method as
private in an abstract class.
I don't. Where did you get that idea?
what is the scope of it within an abstract class?
The abstract class.
The method can be accessed only from within the abstract class. For example, you could have an abstract class with a public final method that makes use of a private helper method.
package arrayafter;
public abstract class Abstract_Demo {
abstract void display();
private void display1() {
System.out.println("Private Method");
}
final void display2() {
System.out.println("final Method");
display1();
}
public static void display3() {
System.out.println("Static methods");
}
}
package arrayafter;
import java.util.Scanner;
public class Practice extends Abstract_Demo{
public static void main(String[] args) {
Practice pr=new Practice();
pr.display();
pr.display2();
Abstract_Demo.display3();
}
#Override
void display() {
// TODO Auto-generated method stub
System.out.println("Abstract method");
}
}

Categories

Resources