面向对象练习

练习一

定义一个Person类,{name,age,job},初始化Person对象数组,有3个person对象,并按照age的值,从小到大进行排序,使用冒泡排序。
注意点:对象的交换方式

public class Person {
    private String name;
    private int age;
    private String job;
    public Person(String name, int age, String job) {
        this.name = name;
        this.age = age;
        this.job = job;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", job='" + job + '\'' +
                '}';
    }
}
class Test01{
    public static void main(String[] args) {
        Person [] person = new Person[3];
        person [0] = new Person("张三",23,"律师");
        person [1] = new Person("李娜",25,"美工");
        person [2] = new Person("吴彦祖",24,"程序员");
        for (int i = 0; i < person.length; i++) {
            for (int j = 0; j < person.length-1-i; j++) {
                if (person[j].getAge() > person[j+1].getAge()){
                    Person indxe = null ;//注意对象的交换方式
                   indxe = person[j];
                   person[j] = person[j+1];
                    person[j+1] = indxe;
                }
            }
        }
        System.out.println("排序后的效果");
        for (int i = 0; i < person.length; i++) {
            System.out.println(person[i]);
        }

    }
}

练习二

写出四种访问修饰符和各自的访问权限

访问修饰符本类同包不同包子类不同包
public
protected×
默认××
private×××

练习三

编写老师类

  1. 要求有属性:name,age,职称post,salary,薪水级别grade
  2. 编写业务方法:introduce(),实现输出一个教师的信息
  3. 编写老师类的三个子类:教授类Professor,副教授类,讲师类。薪水级别为教授1.3/副教授1.2/讲师1.1,且在三个子类中都重写父类的introduce()方法。
  4. 定义并初始化一个子类对象,调用业务方法,实现对象的基本信息后台打印
public class Teacher {
    public String name;
    private int age;
    private double salary;
    private double grade;
    public Teacher(String name, int age, double salary, double grade) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.grade = grade;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public void setGrade(double grade) {
        this.grade = grade;
    }

    public int getAge() {
        return age;
    }

    public double getSalary() {
        return salary;
    }

    public double getGrade() {
        return grade;
    }

    public String introduce() {
        return "Teacher{" +
                "name='" + this.name + '\'' +
                ", age=" + getAge() +
                ", salary=" + getSalary() +
                ", grade=" + getGrade() +
                '}';
    }
}
class Professor extends Teacher{
    public Professor(String name, int age, double salary, double grade) {
        super(name, age, salary, grade);
    }
    @Override
    public String introduce() {
        return super.introduce();
    }
}
class Test002{
    public static void main(String[] args) {
        Professor professor = new Professor("李三",32,30000,1.3);
        System.out.println(professor.introduce());
    }
}

练习四

通过继承实现员工工资核算打印功能
父类:员工类
子类:部门经理,普通员工

  1. 部门经理工资=1000+单日工资x天数x等级(1.2)
  2. 普通员工工资=单日工资x天数x等级(1.0)
  3. 员工属性:name,单日工资,工作天数
  4. 员工方法:(打印工资)
  5. 子类需要重写打印工资的方法
  6. 实例化两个子类,调用各自的打印工资方法,输入单日工资
//员工类
public class Staff {
    public String name;
    private double base;//底薪
    private double daysal;//日薪
    private double grade;//级别
    private int days;//天数
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getBase() {
        return base;
    }
    public void setBase(double base) {
        this.base = base;
    }
    public double getDaysal() {
        return daysal;
    }
    public void setDaysal(double daysal) {
        this.daysal = daysal;
    }
    public double getGrade() {
        return grade;
    }
    public void setGrade(double grade) {
        this.grade = grade;
    }
    public int getDays() {
        return days;
    }
    public void setDays(int days) {
        this.days = days;
    }
    public Staff(String name, double daysal, double grade, int days) {
        this.name = name;
        this.daysal = daysal;
        this.grade = grade;
        this.days = days;
    }
    public String printSal(){
        double sum = this.base+this.daysal*this.days*this.grade;
        return name+"的薪水为="+sum;
    }
}
//部门经理类
class Manager extends Staff{
    public Manager(String name, double daysal, double grade, int days) {
        super(name, daysal, grade, days);
    }
    @Override
    public String printSal() {
        return super.printSal();
    }
}
//普通员工类
class basicStaff extends Staff{
    public basicStaff(String name, double daysal, double grade, int days) {
        super(name, daysal, grade, days);
    }
    @Override
    public String printSal() {
        return super.printSal();
    }
}
class Test004{
    public static void main(String[] args) {
        Manager wang = new Manager("王经理", 500, 1.2, 30);
        basicStaff li = new basicStaff("李三", 400, 1.0, 30);
        wang.setBase(1000);
        System.out.println(wang.printSal());
        li.setBase(0);
        System.out.println(li.printSal());

    }
}

输出结果:
王经理的薪水为=19000.0
李三的薪水为=12000.0

练习五

设计父类:员工类
子类:工人类(Worker),农名类(Peasant),教师类(Teacher),科学家类(Scientist),服务生类(Waiter)

  1. 工人,农民,服务生只有基本工资
  2. 教师不仅有基本工资还有课酬(元/天)
  3. 科学家除基本工资外,还有年终奖
  4. 编写一个测试类将各种类型的员工全年工资打印出来
//员工类
public class Staff {
    public String name;
    private double salary;
    public Staff(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public double printSal(){
        return getSalary()*12;
    }
}
//工人类
class Worker extends  Staff{
    public Worker(String name, double salary) {
        super(name, salary);
    }
}
//老师类
class Teacher extends Staff{
    private double remu;
    public double getRemu() {
        return remu;
    }
    public void setRemu(double remu) {
        this.remu = remu;
    }

    public Teacher(String name, double salary, double remu) {
        super(name, salary);
        this.remu = remu;
    }

    @Override
    public double printSal() {
        return super.printSal()+getRemu()*365;
    }
}
//科学家类
class Scientist extends Staff{
    private double bonus;
    public double getBonus() {
        return bonus;
    }
    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    public Scientist(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }

    @Override
    public double printSal() {
        return super.printSal()+getBonus();
    }
}
//测试类
class Test005{
    public static void main(String[] args) {
        Worker worker = new Worker("李三", 3000);
        System.out.println("农民"+worker.name+"的年收入为="+worker.printSal());
        Teacher teacher = new Teacher("张明",5000,100);
        System.out.println("教师"+teacher.name+"的年收入为="+teacher.printSal());
        Scientist scientist = new Scientist("李想",6000,20000);
        System.out.println("科学家"+scientist.name+"的年收入为="+scientist.printSal());
    }
}

练习六

Grand Father和Son在同一个包,在下方的语句中this和super都可以调用哪些属性和方法

//Grand
class Grand{
 String name = "AA";
 private int age = 100;
 public void g1(){}
}
//Father 
class Father extends Grand{
	String id = "001";
	private double score;
	public void f1(){
	//super可以访问哪些成员?
	//this可以访问哪些成员
	}
	}
//Son
class Son extends Father{
	String name = "BB";
	@Override
	public void g1(){}
	public void show(){
	//super可以访问哪些成员?
	//this可以访问哪些成员}
}

Father 类:
的f1方法中super可以访问:name=“AA”,和g1方法。age变量由于是private修饰且没有get方法,无法访问
this可以访问 name=“AA”,score,id=“001”,g1方法,f1()方法
Son类:
的g1方法中super可以访问:name=“AA”(父类的),id =”001“,g1方法(超类的),f1方法(父类的)
this可以访问:name = “BB”(自己的),id =”001“,g1方法(自己的),f1方法(父类的),show方法

练习七

写出程序结果

class Test{
	String name = "Rose";
	Test(){
	System.out.println("Test");
	}
	Test(String name){
	this.name = name;
	}
}
class Demo extends Test{
	String name = "jack";
	Demo(){
	super();
	System.out.println("Demo");
	}
	Demo(String s){
	super(s);
	}
	public void test(){
	System.out.println(super.name);
	System.out.println(this.name);
	}
	public static void main(String[]args){
		new Demo().test();
		new Demo("john").test();
	}
}

输出结果是:
Test
Demo
Rose
jack
john
jack

练习八

拓展下面的BankAccount类(银行账户)

public class BankAccount{
    private double balance;
    public BankAccount(double initialBalance){
        this.balance = initialBalance;
    }
    public void deposit(double amount){//存款方法
        balance += amount;
    }
    public void withdraw(double amount){//取款方法
    	balance -= amount;
    }
    public double getBalance() {
        return balance;
    }
    public void setBalance(double balance) {
        this.balance = balance;
    }
}

要求:

  1. 在上面类的基础上拓展 新类 CheckingAccount类,对每次存款取款都收取1元的手续费
  2. 在前一个拓展的基础上增加一个新类,SavingAccount使每个月都有利息产生(earnMonthlyInterest方法被调用),并且每月有三次抵扣存取款的手续费。再earnMonthlyInterest方法中重置交易次数
public class BankAccount{
    private double balance;
    public BankAccount(double initialBalance){
        this.balance = initialBalance;
    }
    public void deposit(double amount){//存款方法
        balance += amount;
    }
    public void withdraw(double amount){//取款方法
        balance -= amount;
    }
    public double getBalance() {
        return balance;
    }
    public void setBalance(double balance) {
        this.balance = balance;
    }
}
//CheckingAccount 类
class CheckingAccount extends  BankAccount{
    public CheckingAccount(double initialBalance) {
        super(initialBalance);
    }

    @Override
    public void deposit(double amount) {
        super.deposit(amount-1);
    }

    @Override
    public void withdraw(double amount) {
        super.withdraw(amount+1);
    }
}
//SavingAccount 类
class SavingAccount extends BankAccount{
    public SavingAccount(double initialBalance) {
        super(initialBalance);
    }
    int count = 3;
    double res = 0.1;

    @Override
    public void deposit(double amount) {
        if (count >= 1) {
            super.deposit(amount);
            //免手续费存钱
            count--;
        }else{
            super.deposit(amount-1);
            //扣一块钱到行长的卡里
        }
    }
    @Override
    public void withdraw(double amount) {
        if (count >= 1) {
            super.withdraw(amount);
            //免手续费取钱
            count--;
        }else{
            super.withdraw(amount+1);
            //扣一块钱到行长的卡里
        }
    }
    public void earnMonthlyInterest(){
        super.deposit(this.getBalance()*res);//把利息存进账户
        count = 3;//重置免手续的次数
    }

}
class Test006{
    public static void main(String[] args) {
        SavingAccount s = new SavingAccount(100);
        s.deposit(500);
        s.deposit(500);
        s.deposit(500);
        System.out.println(s.getBalance());
        s.deposit(500);
        System.out.println(s.getBalance());
        s.earnMonthlyInterest();
        s.withdraw(200);
        System.out.println(s.getBalance());
    }
}

练习九

设计一个Point类,其x和y坐标可以通过构造器提供。定义一个子类LabeledPoint,其构造器接收一个标签值和x,y坐标。比如new LabeledPoint(“black”,1929,230.07) 写出对应构造器即可。

public class Point {
    public double x;
    public double y;
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}
class LabeledPoint extends Point{
    public String label;
    public LabeledPoint(String label,double x, double y) {
        super(x, y);
        this.label = label;
    }
}

练习十

编写Doctor类(name,age,sal)有相应的get和set方法,3个参数的构造器
要求重写父类的equals()方法public boolean equals(Object obj)
并判断测试类中创建的两个对象是否相等。相同条件为:属性全相同就算相等

public class Doctor {
    public String name;
    private int age;
    private double salary;
    public Doctor(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj){
            return true;}
        Doctor doc = (Doctor) obj;//向下转型
        return this.name.equals(doc.name) && this.age == doc.getAge() && this.salary == doc.getSalary() ;
    }
}
class Test007{
    public static void main(String[] args) {
        Doctor d1 = new Doctor("李四", 22, 3000);
        Doctor d2 = new Doctor("李四", 23, 3000);
        System.out.println(d1.equals(d2));
    }
}

练习十一

Person类中有run方法和eat方法,他的子类Student类重写了run方法且还有一个自己的study方法。
写出向下转型和向上转型的代码,并说出各自都可以调用什么方法。会输出什么
案例

public class Person {
    public void run(){
        System.out.println("Person run");
    }
    public void eat(){
        System.out.println("Person eat");
    }
}
class Student extends Person{
    @Override
    public void run() {
        System.out.println("Student run");
    }
    public void study(){
        System.out.println("Student study");
    }
}

答案

class Test09{
    public static void main(String[] args) {
        Person person = new Student();//向上转型
        //可以调用Student类的run方法,输出Student run
        person.run();//编译阶段是父类Person的run方法,运行阶段是子类Student的run方法
        //可以调用Person类的eat方法,输出Person eat
        person.eat();//编译和运行都是父类的eat方法,因为子类中没有eat方法
        Student student = (Student) person;//向下转型
        //可以调用Student类的study方法,输出Student study
        student.study();
        //可以调用Student类的run方法,输出Student run
        student.run();//编译和运行都是子类
        //可以调用Person类的eat方法,输出Person eat
        student.eat();
    }
}

练习十二

说出 == 和equals的区别

名称概念用于判断基本数据用于判断引用类型
==比较运算符判断值是否相等判断两个对象的地址是否相同
equalsObject类的方法无法判断默认判断两个对象的地址是否相同

注意点:

  1. equals方法是Object类的方法,所以java中所有类都会继承equals方法
  2. equals虽然默认是判断对象的地址是否相同,但是子类中往往会重写为判断两个对象的属性是否相同

练习十三

案例描述:

  1. 定义一个Student类,Student类有 名称name,性别sex,年龄age,学号stu_id,将4个属性封装到构造器赋值
  2. 定义一个Teacher类,属性有name ,sex,age,工龄work_age,同样封装到构造器
  3. 学生有一个学习的方法(study),输出“我承诺,我会好好学习”
  4. 老师有一个教学的方法(teach),输出”我承诺,我会好好教学“
  5. 学生和老师都有玩的方法(play),学生玩的是足球,老师玩的是象棋。分别返回字符串 xx爱玩足球和xx爱玩象棋,xx代表名字。
  6. 抽象出一个父类Person类,将共同的属性和方法封装到Person类
  7. 定义多态数组,里面保存2个学生和2个老师,要求按年龄从高到低排序
  8. 定义方法,形参为Person类,功能调用学生的study或教师的teach方法。
//Person类
public class Person {
    private String name;
    private char sex;
    private int age;
    public String play(){
        return null;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public char getSex() {
        return sex;
    }
    public void setSex(char sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                '}';
    }
    public String printPlay(){
        return this.play();
    }
    public void printInfo(){}
}
//Student类
public class Student extends Person{
    private int stu_id;
    public Student(String name, char sex, int age, int stu_id) {
        setName(name);
        setAge(age);
        setStu_id(stu_id);
        setSex(sex);
    }
    public void study(){
        System.out.println("我承诺,我会好好学习");
    }
    @Override
    public String play() {
        return getName()+"爱玩足球";
    }
    public int getStu_id() {
        return stu_id;
    }
    public void setStu_id(int stu_id) {
        this.stu_id = stu_id;
    }
    @Override
    public void printInfo() {
        System.out.println("学生的信息:\n" +
                "姓名:"+getName()+"\n年龄:"+getAge()+"\n性别:"+getSex()+"\n学号:"+getStu_id());
        study();
    }
}
//Teacher类
public class Teacher extends Person{
    private int work_Age;

    public Teacher(String name, char sex, int age, int work_Age) {
        setName(name);
        setAge(age);
        setWork_Age(work_Age);
        setSex(sex);
    }
    public void teach(){
        System.out.println("我承诺,我会好好教学");
    }

    @Override
    public String play() {
        return getName()+"爱下象棋";
    }
    public int getWork_Age() {
        return work_Age;
    }
    public void setWork_Age(int work_Age) {
        this.work_Age = work_Age;
    }

    @Override
    public void printInfo() {
        System.out.println("老师的信息:\n" +
                "姓名:"+getName()+"\n年龄:"+getAge()+"\n性别:"+getSex()+"\n工龄:"+getWork_Age());
        teach();
    }
}
//测试类
public class Test006 {
    public static void main(String[] args) {
        Person[] person = new Person[4];
        person [0] = new Student("李涛",'男',18,0012);
        person [1] = new Student("宋琪",'女',19,0022);
        person [2] = new Teacher("张杰",'男',30,3);
        person [3] = new Teacher("李娜",'女',28,5);
        //使用冒泡循环进行排序
        for (int i = 0; i < person.length-1; i++) {
            for (int j = 0; j < person.length-1-i; j++) {
                if (person[j].getAge() > person[j+1].getAge()){
                    Person indx = null;
                    indx = person[j];
                    person[j] = person[j+1];
                    person[j+1] = indx;
                }
            }
        }
        //查看排序后的情况
        for (int i = 0; i < person.length; i++) {
            person[i].printInfo();
            System.out.println(person[i].printPlay());
            System.out.println("---------------");
        }
    }
}

输出结果:

学生的信息:
姓名:李涛
年龄:18
性别:男
学号:10
我承诺,我会好好学习
李涛爱玩足球

===========

学生的信息:
姓名:宋琪
年龄:19
性别:女
学号:18
我承诺,我会好好学习
宋琪爱玩足球

===========

老师的信息:
姓名:李娜
年龄:28
性别:女
工龄:5
我承诺,我会好好教学
李娜爱下象棋

===========

老师的信息:
姓名:张杰
年龄:30
性别:男
工龄:3
我承诺,我会好好教学
张杰爱下象棋

===========

练习十四

在main方法中执行:C c = new C(); 会输出什么?

class A{
	public A(){
	System.put.println("我是A类的无参构造器");
	}
]
class B extends A{
	public B(){
	System.put.println("我是B类的无参构造器");
	}
	public B(String name){
	System.put.println(name+"我是B类的有参构造器");
	}
}
class C extends B{
	public C(){
	this("hello");
	System.put.println("我是C类的无参构造器");
	}
	public C(String name){
	super("hahaha");
	System.put.println(name+"我是C类的有参构造器");
	}
}

在main方法中执行 C c = new C();

  1. 首先由于没有传入参数,默认调用无参构造器 ,
  2. 由于无参构造器的第一行语句是this(“hello”);,所以会调用C类的有参构造器,且传入参数hello
  3. C类的有参构造第一条语句是super(”hahaha“)所以会调用B类的有参构造器
  4. B类的有参构造器由于默认会有一个super();调用B类的父类构造器,所以会进入A类的无参构造器输出:我是A类的无参构造器
  5. 然后再回到B类有参构造器将传入的”hahaha“拼接语句输出 hahaha我是B类的有参构造器
  6. 接着返回C类的有参构造器,输出下面的语句 用C类的无参构造器传入的”hello“凭借输出: hello我是C类的有参构造器
  7. 再返回到C类的无参构造继续输出下面的:我是C类的无参构造器
    所以会输出:
    我是A类的无参构造器
    hahaha我是B类的有参构造器
    hello我是C类的有参构造器
    我是C类的无参构造器

练习十五

  • 什么是多态,多态的具体体现有哪些?
    -. 多态:方法或对象具有多种形态,是OOP编程的第三特征,建立再封装和继承之上
    -. 方法的多态:重载,重写
    -.对象的多态:对象的编译类型和运行类型可以不一致,编译类型在定义时就确定了,无法变化
    而运行类型是可以变化的,可以通过getClass()查看实时的运行类型
    列如:
Class A{}
Class B extends A{}
Class C extends B{}

A obj = new B();
此时obj的编译类型是A ,运行类型是B
A b1 = obj
此时obj将 它那的对象地址复制一份给了 b1
obj = new C()
此时 obj的运行类型变化成了 C
obj = b1
此时b1将 它那的对象地址复制一份给了 obj,所以obj的运行类型又变回了B

  • java的动态绑定机制是什么?
    1. 当调用对象的方法时,该方法会和对象的内存地址(运行类型),绑定在一起,如果没有找到,则就父类找
    2. 当调用对象的属性时,没有动态绑定机制,谁调用,就使用谁那里的。也就是看编译类型

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值