面向对象之继承,多态,抽象类、接口
学习了基础的java知识继承,需要几个题目来巩固、理解
题目一:
图形面积计算
我们有一些图形的边长数据,这些图形包括三角形和矩形,请你编写一个程序求出它们的面积。
请你实现一个基础图形类Graph,然后实现三角形类Triangle和矩形类Rectangle,继承自Graph。根据输入的边数实现不同的对象,并计算面积。
输入格式:
一行,一个整数n,表示图形个数。
n行,每行是用空格隔开的整数。
输出格式:
n行,每行是一个图形的面积。
输入样例:
2
5 5
6 6 6
输出样例:
25
15
解法:定义抽象类求面积
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int s=scanner.nextInt();
int []arr1=new int[2];
int []arr2=new int[3];
for (int i = 0; i < arr1.length; i++) {
arr1[i]=scanner.nextInt();
}
for (int i = 0; i < arr2.length; i++) {
arr2[i]=scanner.nextInt();
}
Graph g = new R(arr1[0], arr1[1]);
int result=g.Sum();
System.out.println(result);
Graph g1 = new T(arr2[0], arr2[1],arr2[2]);
int result1=g1.Sum();
System.out.println(result1);
}
}
abstract class Graph {// 抽象类Grape
public abstract int Sum();// 抽象方法Sum
}
//长方形rectangle继承抽象类,需实现所有方法或者是把子类定义成抽象类
class R extends Graph {
int length;
int width;
public R(int length,int width){//用构造方法对length、width进行初始化
this.length=length;
this.width=width;
}
@Override
public int Sum() {
// TODO Auto-generated method stub
return length * width;
}
}
class T extends Graph {
int length;
int width;
int height;
public T(int length,int width,int height){
this.length=length;
this.width=width;
this.height=height;
}
@Override
public int Sum() {
int p=(length+width+height)/2;
int s=(int) Math.sqrt(p*(p-length)*(p-height)*(p-width));//已知三边求三角形的面积
return s;
}
}
题目二
设计一个系统:
XXX门的实现过程:
流程:
设计一张抽象的门Door,那么对于这张门来说,就应该拥有所有门的共性,开门openDoor()和关门closeDoor();然后对门进行另外的功能设计,防盗–theftproof()、防水–waterproof()、防弹–bulletproof()、防火、防锈……
要求:利用继承、抽象类、接口的知识设计该门
public class Test {
public static void main(String[] args) {
gongneng door=new gongneng();
door.openDoor();//开门
door.closeDoor();//关门
door.bulletproof();//防弹
door.theftproof();//防盗
door.waterproof();//防水
}
}
interface Door {// 定义一个接口的Door
public void openDoor();// 属性开门
public void closeDoor();// 关门
}
/*
* 实现接口两种方法: 方法一:实现接口中的所有方法 方法二:子类定义为抽象类
*/
class gongneng implements Door {
@Override
public void openDoor() {
// TODO Auto-generated method stub
System.out.println("开门");
}
@Override
public void closeDoor() {
// TODO Auto-generated method stub
System.out.println("关门");
}
public void theftproof() {
System.out.println("这个门具有防盗功能");
}
public void waterproof() {
System.out.println("这个门具有防水功能");
}
public void bulletproof() {
System.out.println("这个门具有防弹功能");
}
}
输出结果:
开门
关门
这个门具有防弹功能
这个门具有防盗功能
这个门具有防水功能
题目三:
设计一个接口用于涨工资,普通员工一次能涨10%,经理能涨20%.
要求:
1.定义Man类,有name,address,俩个属性,并写出构造方法。
2.定义Employee类,有employeeId(员工编号)、wage(工资)、workAge(工龄)三个属性,写出该类的构造方法。
3.定义Manager类,有level(级别)属性,写出构造方法。
4.定义EmployeeTest类,产生一个员工和一个经理并输出工资信息。
public class EmployeeTest {
public static void main(String[] args) {
Employee m=new Employee("mary","Hubei",5000, 12, 3);
System.out.println("姓名:"+m.name+" 地址:"+m.address+" 原来工资:"+m.wage+" 现在工资:"+m.addMoney()+" 员工编号: "+m.getEmployeeid()+" 工作时间:"+m.getWorkAge()+"年");
Manager manager=new Manager("harier","Beijing",8000,"总经理");
System.out.println("姓名:"+m.name+" 地址:"+m.address+" 原来工资:"+m.wage+" 现在工资:"+manager.addMoney()+" 级别:"+manager.getLevel());
}
}
interface Money{//定义一个Money接口,实现加工资
public double addMoney();//抽象类
}
class Man{//定义一个Man,有name,address,wage属性
static String name;
static String address;
static double wage;
public Man(String name,String address, double wage){
this.name=name;
this.address=address;
this.wage=wage;
}
public static String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public static double getWage() {
return wage;
}
public void setWage(double wage) {
this.wage= wage;
}
}
class Employee extends Man implements Money{//员工Employee继承Man实现接口
private int employeeid;
private int workAge;
public Employee(String name,String address,double wage,int employeeid,int workAge){
super(name,address,wage);
this.employeeid=employeeid;
this.workAge=workAge;
}
public int getEmployeeid(){
return employeeid;
}
public void setEmployeeid(int employeeid){
this.employeeid=employeeid;
}
public int getWorkAge(){
return workAge;
}
public void SetWorkAge(int workAge){
this.workAge=workAge;
}
@Override
public double addMoney() {
return wage*(1+0.1);
}
}
class Manager extends Man implements Money{
private String level;
public Manager(String name,String address,double wage ,String level){
super(name, address,wage);
this.level=level;
}
public String getLevel(){
return level;
}
public void setLevel(String level){
this.level=level;
}
@Override
public double addMoney() {
// TODO Auto-generated method stub
return wage*(1+0.2) ;
}
}
输出结果:
姓名:mary 地址:Hubei 原来工资:5000.0 现在工资:5500.0 员工编号: 12 工作时间:3年
姓名:harier 地址:Beijing 原来工资:8000.0 现在工资:9600.0 级别:总经理
题目四
需要在TestStudent类中定义一个run()方法,这个run()方法即处理boy的方法,又要处理girl的方法
package test;
public class Student {
public void run(){
System.out.println("A student is running");
}
}
class boy extends Student{
public void run(){
System.out.println("A boy is running");
}
}
class girl extends Student{
public void run(){
System.out.println("A girl is running");
}
}
package test;
public class TestStudent {
public void run(Student student) {
student.run();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TestStudent testStudent = new TestStudent();
//用父类型的引用生成子类型的对象,向下类型转换
Student student=new boy();
student.run();
//向上类型转换
girl girl=new girl();
testStudent.run(girl);
}
}
输出结果:
A boy is running
A girl is running
【说明】:这种程序比较容易维护,如果子类继续添加,只要知道父类,子类就都可以作为参数传上去,因为Student是父类型,子类型的引用都可以传上去,实现先上转型,一个方法就可以应付所有的此类需求,这就是多态给我们带来的好处,它屏蔽掉了子类的差异性,用一个公共的父类去标示着接口,不管增加了多少子类,都可以通过将父类型的引用作为一个参数,具体的子类引用传过去就可以了。