Initialize a class having another class object as member variable - java

This is my first class:
package trickycorejava;
public class InnerClass {
int id;
oneClass oneClass;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public trickycorejava.oneClass getOneClass() {
return oneClass;
}
public void setOneClass(trickycorejava.oneClass oneClass) {
this.oneClass = oneClass;
}
public InnerClass(int id, trickycorejava.oneClass oneClass) {
this.id = id;
this.oneClass = oneClass;
}
public InnerClass(int id){
this.id = id;
}
}
class oneClass {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This is the class where the main method exists, observe that the package is different:
package trickycorejava.constructor;
import trickycorejava.InnerClass;
public class InnerClassTest {
public static void main(String[] args) {
InnerClass innerClass = new InnerClass(1);
}
}
How can I initialize the InnerClass with constructor in this case? If I use
InnerClass innerClass = new InnerClass(1, new oneClass("Test"));
I get the error that oneClass is not public cannot be access from outside package.

As Turing85 pointed out the oneClass should be in it's own file, otherwise it's going to be package-private which means you can only access it from classes of the same package.
Is there another way? There is, but it's not going to be a simple constructor call. Using reflection you can bypass class, field and method invocation protection.
public class InnerClassTest {
public static void main(String[] args) throws Exception {
Constructor<OneClass> constructor = OneClass.class.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
OneClass instance = constructor.newInstance("John");
InnerClass innerClass = new InnerClass(1, instance);
}
}
What this does is that it finds the constructor that is private to Main because the class is package-private. Then it disables the protection of it, note that these are temporary, the Constructor object is a new reference and only allows the invocation via this reference.
But I don't recommend doing this extensively. Reflection has some use cases, mainly to aid programmers in frameworks like Spring, but otherwise it can break object oriented patterns.

Related

Java: Calling a parent's method with child's member variable

Let's say I have an abstract parent class that has member variables which are used in a method.
public abstract class Person{
public String jobTitle;
public void printJob(){
System.out.println(jobTitle);
}
}
If I now have two child classes
public class Teacher extends Person{
public String jobTitle = "Teacher";
}
public class Janitor extends Person{
public String jobTitle = "Janitor";
}
and I want to avoid code cloning, i.e. implementing the same printJob()-method in both classes, I now have a problem, since the printJob()-method is unable to access member variables of the child classes.
Is there any way that i can call a parent classes' method but have the method use the child classes' member variables?
You can use abstract methods like this
public abstract class Person {
public void printJob() {
System.out.println(getJobTitle());
}
protected abstract String getJobTitle();
public static void main(String[] args) {
Person teacher = new Teacher();
Person janitor = new Janitor();
System.out.println(teacher.getJobTitle());
System.out.println(janitor.getJobTitle());
}
}
class Teacher extends Person {
#Override
protected String getJobTitle() {
return "Teacher";
}
}
class Janitor extends Person {
#Override
protected String getJobTitle() {
return "Janitor";
}
}
Updated after op's comment for code cloning...
public class Person {
public static void main(String[] args) {
System.out.println(new Teacher().job);
System.out.println(new Janitor().job);
}
private static class Teacher extends Person {
private String job = "Teacher";
}
private static class Janitor extends Person {
private String job = "Janitor";
}
}

java - sending variables through nested classes

I have a class that has a variable of type Name.
public class Holder {
private Name name;
private int snumber;
The Name class has two strings called first and last that are assigned values by setter methods. I would like to send over the strings from the Name class to name in the Holder class, but I'm having trouble doing so. I think I've taken a step in the right direction by doing this
public class Holder {
private Name name;
private int snumber;
public void setName(){
name = new Name();
name.getFirst();
name.getLast();
}
but I can't say that I really know what the correct approach is. I also tried name.setFirst(getFirst) but that doesn't work. Any ideas would be appreciated.
The same way you would if the class wasn't nested.
Your setName() method should take a parameter (maybe 2, first and last) and then invoke the name.setFirstName(), name.setLastName() methods.
Right now, your setName() method isn't doing anything.
E.G:
public class Holder
{
private Name name;
private int snumber;
public Holder()
{
this.name = new Name();
}
public void setName(String firstName, String lastName)
{
this.name.setFirst(firstName);
this.name.setLAst(lastName);
}
}
Here is a good article explaining the relationship between Java inner and outer classes:
https://www.tutorialspoint.com/java/java_innerclasses.htm
class Outer_Demo {
// private variable of the outer class
private int num = 175;
// inner class
public class Inner_Demo {
public int getNum() {
System.out.println("This is the getnum method of the inner class");
return num;
}
}
}
public class My_class2 {
public static void main(String args[]) {
// Instantiating the outer class
Outer_Demo outer = new Outer_Demo();
// Instantiating the inner class
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
System.out.println(inner.getNum());
}
}
Note that the example creates instances of both "Outer_Demo" AND "Inner_Demo (outer.new Inner_Demo();).
Ok, so I figured something out that works.
public class Holder {
private int snumber;
private Name name;
public void setName(Name n){
name=n;
}
public Name getName(){
return name;
}

How can I express object which should be 2 different classes at the same time

Today I had test in OOP and I was given the following task to code:
Imagine you have two classes: Employee (which represents being an employee) and Ninja (which represents being a Ninja). An Employee has both state and behaviour; a Ninja has only behavior. You need to represent an employee who is also a ninja (a common problem in the real world). By creating only one interface and only one class (NinjaEmployee), show how you can do this without having to copy method implementation code from either of the original classes. Test your code in main method
I did not really understand the problem well, but this is the solution I came with (I know it's not what was asked):
I created 4 classes except main. As Employee has state and behaviour I came up with this code:
public class Employee {
private int ID;
private String Name;
private double salary;
public Employee(int ID, String Name, double salary) {
this.ID = ID;
this.Name = Name;
this.salary = salary;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void startWorking() {
System.out.println("Started Working");
}
}
Class ninja has only behaviour:
public class Ninja {
public Ninja(){}
public void moveNinja(){
System.out.println("Ninja moved");
}
}
Class NinjaEmployee:
public class NinjaEmployee extends Employee implements MyInterface {
public NinjaEmployee(int ID, String Name, double salary) {
super(ID, Name, salary);
}
public void moveNinja() {
System.out.println("Ninja Moved");
}
}
Interface which does not make sense in my code:
public interface MyInterface {
public void moveNinja();
public void startWorking();
}
Main class:
public static void main(String[] args){
MyInterface em = new NinjaEmployee(123,"Sandro",1000000);
em.moveNinja();
em.startWorking();
}
My question is following:
1) Specifically/Technically what was asked in test?
2) What would be correct approach/code for given problem?
Nice question.
The key point of the question is:
we should use one interface.
Ninja class should have some methods (not attributes).
So we should try to use these key point.
I provide a class diagram below:
First of all: We have Employee class and implement it like other simple classes. It has some implemented attributes and classes.
Secondly: We have an Interface named Ninja_Interface that have some method declarations about ninja. (moveNinja1 and moveNinja2)
Thirdly: Ninja Class that implemented (or Realized) Nijna_Interface and have some implementation of any method declarations in Ninja_Interface.
Fourthly: the NinjaEmployee class. It inherited from Employee. So it has all Employee's attributes and methods. Also it implements Ninja_Interface. So it should implements all Ninja_Interface methods declarations. On the other hand, NinjaEmployee have an instance of Ninja (notice that Ninja class implements all Ninja_Interface methods). So, In Ninja_Employee class, in implementation of Ninja_Interface methods, we can use Ninja instance methods to call.
For example some parts of NinjaEmployee is like below code:
private Ninja ninja=new Ninja();
public void moveNinja1()
{
ninja.moveNinja1();
}
public void moveNinja2()
{
ninja.moveNinja2();
}
Main question is: why Ninja class should have only some methods?
It is because of Ninja class is just the implementations of Ninja_Interface methods and there no need to have attributes. So instances of Ninja class are the same. So we can declare Ninja attribute in NinjaEmployee as static attribute.
Finally: we can add some attributes of ninja into NinjaEmployee class too.
I don't know correct answer (task is kinda not very strictly defined, there is some unclear moments), but i would do something like this:
public interface IAmNinja {
public void moveNinja();
}
public interface IAmEmployer {
public void startWorking();
}
public class NinjaEmployee implements IAmNinja, IAmEmployer {
private Ninja _ninja;
private Employer _employer;
public NinjaEmployee(int ID, String Name, double salary) {
_employer = new Employer(ID, Name, salary);
_ninja = new Ninja();
}
public void moveNinja() {
_ninja.moveNinja();
}
public void startWorking() {
_employer.startWorking();
}
}
You cant create 1 object of 2 class es
You can extend class so whenever child class is instantiated it calls parent class constructor
Then You can create object of another class in that constructor
Add employees in array and add option to add employee in ninja? 1.yes or 2.no?
if yes , add to ninja..then in main method print names of ninja using for loop one by one

java nashorn accessing superclass members

Im working with nashorn engine im trying to extend following java class
public abstract class AbstractClass {
protected String name;
protected long id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public void init() {
}
Javascript code: In the method init() i want to access superclass members (directly set value of protected fields or use public setters)
var extended = Java.extend(AbstractClass.static , {
init: function() {
extended.name = "name"; //name is null
setName("name") //exception <eval>:6 ReferenceError: "setName" is not defined
}
});
In java i create object instance and call init method, but field "name" is null.
i've also tried to use Java.super(extended ).setName("name"); but this threw an exception <eval>:7 TypeError: Cannot call undefined
How can i access superclass members from javascript and nashorn?
Java.extend creates a subclass and not a subclass instance. But Java.super requires a subclass instance as an argument. So, the following script works:
var extended = new (Java.extend(Java.type("AbstractClass"))) {
init: function() {
Java.super(extended).setName("foo");
}
};
extended.init();
print(extended.name);
Somewhat larger example usage of Java.super is here
https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-java_super

How to access private data member outside the class?

I am trying to access the private data member of inner class outside the outer class.
Please help me?
You don't - that's the whole point of it being private.
The inner class can expose the data via a property, of course:
public class Outer {
public class Inner {
private final String name;
public Inner(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
public class Other {
public void foo() {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner("Foo");
// Can't access inner.name here...
System.out.println(inner.getName()); // But can call getName
}
}
... but if the inner class wants to keep it private, then you shouldn't try to access it.
Create public getter setter methods inside the inner class for private variables. Then create an object and call them to access private data. You can't directly access private data.
you cant access a private data. If ýou have other thoughts of accessing it use public getter method returning that private data.
you can access private data member using getter method ex
package pack;
import java.io.ObjectInputStream.GetField;
public class abc {
private int num = 2;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
class otherClass {
public static void main(String[] args) {
abc obj = new abc();
System.out.println(obj.getNum());
}
}

Categories