Java class inside other class, constructor - java

I would like to create one class and then another class inside. This class will be directly connected with superior class. It should look like following (not code, just schema):
class company
string name
class employee
string firstName, lastName;
int age
Of course, I have constructors etc. Now I want to create company 'g' and employee f m of age 2 inside of that company. Maybe it is not justified to make class inside another class and I should just create class employee with field company?
Code below does not work, compiler says: an enclosing instance that contains company.employee is required
nowa=new company('g',2);
nowa.prac=new company.employee('f','m',2);
Full code below:
public class program
{
public static class company
{
char name;
int duration;
public class employee
{
public char imie,nazwisko;
public int wiek;
public employee(char a,char b,int w)
{
imie=a;
nazwisko=b;
wiek=w;
}
}
public company(char n,int c)
{
name=n;
duration=c;
}
}
public static void main(String []args)
{
company nowa=new company('g',2);
nowa.empl=new employee('f','m',2);
}
}

try
nowa.prac = nowa.new firma.pracownik('f','m',2);
Here is more on why:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

This would be my approach
public class Employee {
//...code
}
public class Company {
//...code
private List<Employee> employees;
}
public static void main(String []args)
{
Company nowa=new company('g',2);
nowa.getEmployees.add(new Employee('f','m',2));
}
}
The main changes from your approach are:
Both classes are in its own file (both are top level classes).
Company has an List of Employees (a company HAS employees). With a List you can add and remove easily employees for a given Company.
Class names are capitalized (according to Java naming conventions by using Upper Camel Case).

Your inner class employee is not static, so you need an instance of the outer class to create an inner class instance. An employee may not exist without a company!
company nows = new company('g',2);
nowa.empl = nowa.new employee('f','m',2);
In this case the inner class instances have an implicit reference to the outer class instance (use company.this inside employee to access it).
If you want to make the classes more independent, you can make employee a status inner class without the reference to the outer class:
public static class employee
...
company nows = new company('g',2);
nowa.empl = new employee('f','m',2);

Related

How to use methods defined in anonymous class outside of it?

May I know how can I use/call the age method? Here is the Student class.
class Student {
public static void address(){
System.out.println("streetB");
}
}
public class School {
public static void main(String[] args) {
Student gg = new Student() {
public void age() {
System.out.println("9");
}
};
//how to call age() method here?
}
}
You are probably looking for something different, as you just created new class here that extends Student class, but it is anonymous so you can just access that new method as it does not belong to Student class.
If you are using java 10 then you can use var
class Student {
public static void address(){
System.out.println("streetB");
}
}
public class School {
public static void main(String[] args) {
var gg = new Student() {
public void age() {
System.out.println("9");
}
};
gg.age();
}
}
But that would be probably pretty bad idea, as there is just no reason to do such weird thing.
(var works here because it can represent that anonymous class at compile time)
You should probably add age field and method to Student class
Since gg is declared as Student and there is no age() method in that class, compiler will not allow you to call gg.age() because it is not guaranteed that every Student instance will be able to support it.
Pre java 10 solutions (if you are using Java 10 or later read this answer)
What you can try is reflection mechanism through which you can
gg.getClass() to get class literal representing actual type of object held by gg variable,
then getDeclaredMethod("age") to get age method declared in that class,
then invoke(gg) to call that method on object held by gg.
In short
gg.getClass().getDeclaredMethod("age").invoke(gg);
Other way would be not assigning created instance of anonymous class to any reference which would limit its possibility and call method directly on created object like
new Student() {
public void age() {
System.out.println("9");
}
}.age();
but this way we can't reuse that object anywhere later (because we don't have reference to it).

accessing fields of a class in Java

I am completely new to Java.
I was practicing a code about a person eating some fruit. I have 3 classes
Fruit Class:
public class Fruit {
String fruitname = "grapes";
}
Person Class:
public class Person {
void eat(Fruit f) {
System.out.println("person is eating " + f.fruitname); // how can I do f.fruitname
}
}
Test Class:
public class TestFruit {
public static void main(String[] args) {
Person p = new Person(); // person object
Fruit f = new Fruit(); // fruit object
p.eat(f);
} // eat method of person class
}
output:
person is eating grapes
For accessing fields of a class, Object of that class is created.
My question is:
In Person class, how can I access fruitname field of Fruit class (i.e., writing f.fruitname) without instantiating Fruit class in Person class?
fruitname is a data member of Fruit class and instance member don't exist until object is created.
I have just started learning Java, and I am stuck here. Please help me to understand.
What you're doing does not work because you're not declaring the member field as public:
public String fruitname = "grapes";
Only then you can even compile this:
System.out.println("person is eating " + f.fruitname);
Note that in Java fields are package private per default (see also). This means that the field can be private but in this case you can only access this field in classes which reside in the same package.
However, in general one creates getter and setter methods like this:
public class Fruit {
private String fruitname = "grapes";
public String getFruitname() {
return fruitname;
}
public void setFruitname(String fruitname) {
this.fruitname = fruitname;
}
}
which will allow you to access the class member fruitname like this:
public class Person {
public void eat(Fruit f) {
System.out.println("person is eating " + f.getFruitname());
}
}
Depending on your IDE you might be able to right click the field (or somewhere in the class) and find something like Generate.. > Getters & Setters which makes the whole act less annoying.
Your problem is, that you dont encapsulate the Fruit class correctly.
The current field is package-private so only the class itself and other classes from the same package can access the field. When starting to use concurrency you really need to encapsulate your fields right in order to guard them aswell.
I suggest looking into the Annotation-Preprocessor Lombok since it will help you a lot by generating methods later on. You would just need to add two annotations above your class or the fields in it that should be encapsulated.
An encapsulated and documented version of your Fruit class would look like this:
package me.yourname.yourproject;
import javax.annotation.Nullable;
public class Fruit {
#Nullable
private String name;
/**
* Constructs a fruit without a name.
*/
public Fruit(){
}
/**
* Constructs a fruit with an initial name.
*
* #param name The fruits initial name.
*/
public Fruit(String name){
this.name = name;
}
/**
* Sets the name of the fruit.
*
* #param name The fruits new name.
*/
public void setName(#Nullable String name){
this.name = name;
}
/**
* Gets the fruits current name.
*/
#Nullable
public String getName(){
return this.name;
}
}
So it looks like you need to read up on Creating an object in Java. That's not a bad thing! OO design is hard when you're a beginner.
To answer you're question, you have to instantiate the fruitname object, and then mark it public (or preferably write a getter/setter)
public class Fruit {
private string name;
public Fruit(String name) {
this.name=name;
}
public String getName() {
return this.name;
}
}
Create this object with something like:
Fruit f=new Fruit("peach");
System.out.println(f.getName());
If what you want is to access it in Person without having an instance of Fruit:
Your fruitname is an instance variable. By declaring it 'static' you make it a class member and then you can access it using Fruit.fruitname
You can make it 'public' to allow access from anywhere. As in
public static string fruitname = "grapes";
Now you don't need an instance of Fruit to access fruitname.
Your Person call can look as follows:
public class Person {
void eat() {
System.out.println("person is eating " + Fruit.fruitname);
}
}

How to access outer class variable using inner static class object

I'm studying inner classes in java. I have seen that if inner class is non static then it can easily access the outer class variable. But what if inner class is static, then how can we take a access of outer class's variable using static's class object ?
Below is my code, where am accessing outer class variable from inner class
package org;
public class Outerclass {
String name = "Europe";
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
System.out.println(this.name);
}
static class innerclass {
void updatename() {
Outerclass o = new Outerclass();
o.setname("USA");
}
}
public static void main(String[] args) {
Outerclass b = new Outerclass();
b.name; // why this error here ? "Syntax error, insert "VariableDeclarators" to complete LocalVariableDeclaration"
innerclass i = new innerclass();
i.updatename();
}
}
You can't access non-static contents inside the static content
When we create static inner class by default it will created as a outer template as a association of inner template. So we can load both together but only static things can be inside the static inner class.
Now there are no connection between objects of the classes. But there are connection between the templates.
Following is your code I have done some modification might help you
public class Demo {
String name = "Europe";
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
System.out.println(this.name);
}
static class innerclass {
void updatename() {
Demo o = new Demo();
o.setname("USA");
}
}
public static void main(String[] args) {
Demo b = new Demo();
String a = b.name; // why this error here ? "Syntax error, insert "VariableDeclarators" to complete LocalVariableDeclaration"
System.out.println(a);
innerclass i = new innerclass();
i.updatename();
}
}
Inner static class behives same as normal class:
can access static property/method of outer class
can't non-access static / methods of outre class directly, they will require an outerclass instance reference to do so.
it does not rquire an instance of outer class to be created
It is used mostly in two scenarios:
you are creating a group of classes with similar nature/function, and you want to keep them under one 'Napespace'
you want to create a private class that will not be visible to anyone, except to outter class (private static inner class). That way you can create interface implementations visible only to your outer class.
Non-static inner class:
it requires instance of outer class to be created
it can access methods and properties of outer class.
Quote:
...inner classes can access all members of the declaring class, even
private members. In fact, the inner class itself is said to be a
member of the class; therefore, following the rules of object-oriented
engineering, it should have access to all members of the class.

Define the static with Object in java

An interviewer asked me this:
class Employee{
private string empname;
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
}
class EmpDetails{
private static Employee emp;
public static List fillData(){
emp=new Employee();
List l=new ArrayList();
System.out.println("static after new creation fillData"+System.identityHashCode(emp));
emp.setEmpname("suresh");
emp.setDesignation("Sr.Software Engineer");
l.add(emp);
emp=new Employee();
System.identityHashCode(emp);
System.out.println("static after new creation fillData"+System.identityHashCode(emp));
emp.setEmpname("Prasad");
emp.setDesignation("Software Engineer");
l.add(emp);
return l;
}
}
What happens if define below
private static Employee emp;
What is advantage with define static and non-static non access modifer with employee object?
If a field is defined static, then the value of that field is shared by all the instances of a that particular class. In your case how ever, that field is defined as private, which restricts instances of the class to access it outside the class. When your fill dataget() called it will create the list of Employee and static emp field will hold the value of the last emp("Prasad"). If any other instance of class EmpDetails is created and you try to access emp without calling fillData, using some other method e.g. GetEmp(), then it will return the last value for emp which was set to "Prasad".
With respect to design, this approach is not correct, as EmpDetails class will be pointing to one Employee due to static Employee object.
If you define a static Employee member field in theEmpDetails class - this means that all EmpDetails instances share the same Employee instance. The rest of your question doesn't really make much sense without more context.
You should consider to read up on the difference between instance variables and class variables, for example by reading the Oracle's tutorial on the topic.

Java, how to make variable of the upper class stays null; how to 'hide' variable from the subclass?

I have four classes. Class Person, and three more, Student, Professor, Tutor, each of which extends class Person. Class Person has 2 variables studentID and staffID. However, only student can have studentID != null, and Tutors and Professors can have staffID != null. Now when creating new object Student, how can I make sure that no matter what staffID always stays null? staffID must remain in class Person, so no moving it around.
The whole point of inheritance is that only values and functions (members) that are valid for a parent class are placed in the parent class, and any child-specific members are placed in the child class.
Don't abuse OO, move staffID into your child class.
My suggestion would be to create a Staff class that contains staffID, have it inherit Person, then have Professor and Tutor inherit from it. Then move studentID into the Student class. That way only Professor and Tutor have access to staffID and Student does not, and vice versa for studentID. All classes can still be assigned to a Person type.
Create interfaces to restrict operations:
package main;
public interface IsStaff {
public void setStaffId(Integer staffId);
public Integer getStaffId();
}
package main;
public interface IsStudent {
public void setStudentId(Integer studentId);
public Integer getStudentId();
}
Create your Person class:
package main;
public class Person {
protected Integer studentId = null;
protected Integer staffId = null;
}
Create your Student and Staff subclasses with the Interfaces to define the only allowed operations:
package main;
public class Staff extends Person implements IsStaff {
#Override
public void setStaffId(Integer staffId) {
this.staffId = staffId;
}
#Override
public Integer getStaffId() {
return staffId;
}
}
package main;
public class Student extends Person implements IsStudent {
#Override
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
#Override
public Integer getStudentId() {
return studentId;
}
}
And now create your Tutors and Professors:
package main;
public class Tutor extends Staff {
}
package main;
public class Professor extends Staff {
}
Objects of the Student class don't have operations that can affect the staffId, and objects of the Staff class (including the Tutor and Professor subclasses) don't have operations that can affect the studentId. Add other operations as necessary (common ones can go into Person directly).
As a bonus, you can use the interfaces to better define methods, like this:
public void assignParkingSpaceTo(IsStaff staffMember);
public void issueLateSlipTo(IsStudent student);
The studentID should be a member of Student not Person. Likewise Professor and Tutor should both extend a class Faculty which has a staffId which in turn extends Person
Make this variables private and create getter and setter.
Depending of class implement different methods behaviors.
For stasfs - protect setting studentId
for student - protect setting staffId.
don't extend the Person class. Use composition instead.
If you want polymorphism, create a Blammy interface that provides a common interface for Student, Professor, and Tutor. The student ID and staff Id stuff could or could not be part of the Blammy interface.
Each class, Student, Professor, and Tutor would contain a private instance of Person and proxy to any Person functionality they wanted to expose.
Student would have a studentId data member and Professor and Tutor would have a staffId data member. The getStudentId() for profesor and tutor would always return null and the get staffId for student would also always return null.
make the variable private, create getters and setters. Then make your constructor initialize both variables, and simple pass null for student ID for teachers, and null for staffID for students.
constructor --->
public Person(int staffID, int studentID){
this.staffID = staffID;
this.studentID = studentID:
}
when you initialize ---->
Student student = new Person(null, 1234);

Categories

Resources