Practicing OOP with Student and Person I've just learned the OOP concept of abstraction, and I was wondering if I was implementing it correctly in my code and if you guys can point out any bad practices.

test1.java

package OOPConcepts;

import java.util.Scanner;
public class test1 {
    static public Scanner input = new Scanner(System.in);
    public static void main(String[] args) {
        String fName, lName;
        int age;
        Student newPerson = new Student();
        input.close();
    }
}


Person.java

package OOPConcepts;

public class Person
{
    static private int pNumber = 0;
    private int pID;
    public int age;
    private String type;
    public String fName, lName;

    Person()
    {
        pNumber++;
        pID = pNumber;

        System.out.println("Enter first name:");
        String fName = test1.input.next();
        System.out.println("Enter last name:");
        String lName = test1.input.next();
        System.out.println("Enter age:");
        int age = test1.input.nextInt();
        type = "person";
        describe(fName, lName, age);

        System.out.println("Made a " + type);
    }
    public void setType(String type){
        this.type = type;
    }
    public String getType()
    {
        return this.type;
    }
    public void describe(String fName, String lName, int age)
    {
        this.fName = fName;
        this.lName = lName;
        this.age = age;
        System.out.println("Name: " + this.fName + " " + this.lName + "|Age: " + this.age);
    }
}


Student.java

package OOPConcepts;

public class Student extends Person{
    static private int sNumber = 0;
    private int studentID;
    public String major;

    Student()
    {
        sNumber++;
        studentID = sNumber;
        setType("student");

        System.out.println("Who is also a " + getType());
        System.out.println("Enter major: ");
        String major = test1.input.next();
        this.major = major;
    }
    public void setStudentID(int idNumber)
    {
        this.studentID = idNumber;
    }
    public int getStudentID()
    {
        return this.studentID;
    }
}
What is OOP?

There is more to OOP than just class inheritance and your example shows painfully clearly why class hierarchy is almost always completely unable to represent the real world. If a student is a specialized type of a person, then a person can not be a student and a teacher at the same time (e.g. an assistant to a teaching professor). Also, that person can no longer be a part time employee at the cafeteria either, because the person's status has been locked into being a student and student only. Clearly, class inheritance is the wrong tool here. The relation should be composition:

public class Student {
    private final StudentId studentId;
    private final Person person;

    public Student(StudentId studentId, Person person) {
        this.studentId = studentId;
        this.person = person;
    }

    ...
}