知识点
抽象,接口,基础概念练习
-
static 修饰的属性,相较于实例变量,有哪些特别之处(>=3点)
随着类的加载而加载,被类的所有对象共享,可以通过类名调用,也可以通过对象名调用【推荐使用类名调用】
-
final 可以用来修饰哪些结构,分别表示什么意思?
类(不能继承)、变量(值不能改变)、方法( 不能重写)、final 修饰指的是基本类型的数据值不能发生改变、 final 修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
-
类的属性赋值的位置有哪些?先后顺序为何?
-
默认初始化
-
显示初始化/ 代码块中赋值
-
构造器中赋值
-
通过对象调方法或属性赋值
-
-
abstract 能修饰哪些结构? 修饰以后,有什么特点?
类(不能直接实例化,继承必须重写抽象类中抽象方法或者子类为抽象类)、
方法(如果方法定义为抽象方法,类也必须是抽象类且子类 必须重写该方法)
-
接口是否能继承接口? 抽象类是否能实现(implements)接口? 抽象类是否能继承非抽象的类?
是(继承关系,可以单继承也可以多继承),
是(实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口),
是(继承关系,只能单继承,但是可以多层继承)
-
抽象类和接口有哪些共同点和区别?
-
成员区别
-
抽象类
变量,常量;有构造方法;有抽象方法,也有非抽象方法
-
接口
常量;抽象方法
-
-
关系区别
-
类与类
继承,单继承
-
类与接口
实现,可以单实现,也可以多实现
-
接口与接口
继承,单继承,多继承
-
-
设计理念区别
-
抽象类
对类抽象,包括属性、行为(事物)
-
接口
对行为抽象,主要是行为
-
抽象,接口,基础应用练习
1.按要求实现下列问题: 1) 动物类Animal包含了抽象方法 abstract void shout(); 2) Cat类继承了Animal,并实现方法shout,打印“猫会喵喵叫” 3) Dog类继承了Animal,并实现方法shout,打印“狗会汪汪叫” 4) 在测试类中实例化对象Animal a1 =new Cat(),并调用a1的shout方法 5) 在测试类中实例化对象Animal a2 =new Dog(),并调用a2的shout方法 //测试类 public class demo3{ public static void main(String[] args) { //在测试类中实例化对象Animal a1 =new Cat(),并调用a1的shout方法 Animal a1=new Cat(); a1.shout(); // 在测试类中实例化对象Animal a2 =new Dog(),并调用a2的shout方法 Animal a2=new Dog(); a2.shout(); } } //动物类Animal包含了抽象方法 abstract void shout() public abstract class Animal{ abstract void shout(); } //Cat类继承了Animal,并实现方法shout,打印“猫会喵喵叫” public class Cat extends Animal{ @Override void shout() { System.out.println("猫会喵喵叫"); } } //Dog类继承了Animal,并实现方法shout,打印“狗会汪汪叫” class Dog extends Animal{ @Override void shout() { System.out.println("狗会汪汪叫"); } }
2./*定义一个抽象类Person, 有name,age,sex三个属性,创建构造函数,给这三个属性赋值,重写打印描述信息方法,打印三个属性值;这个类中有两个抽象方法work和hello; 定义两个子类Teacher,Student;教师的work实现是:教书育人,hello实现是:“同学好”; 学生的work实现是:认真学习,hello实现是“老师好”。*/ //测试类 public class demo3{ public static void main(String[] args) { Person a=new Teacher("小王",23,"男"); a.show(); a.work(); a.hello(); Person b=new Student("小王",23,"男"); b.show(); b.work(); b.hello(); } } //定义一个抽象类Person public abstract class Person{ //有name,age,sex三个属性 private String name ; private int age; private String sex; //创建构造函数,给这三个属性赋值 public Person() { } public Person(String name, int age, String sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } //重写打印描述信息方法,打印三个属性值 public void show(){ System.out.println(getName()+", "+getAge()+", "+getSex()); } //这个类中有两个抽象方法work和hello public abstract void work(); public abstract void hello(); } //定义子类Teacher public class Teacher extends Person{ public Teacher(String name, int age, String sex) { super(name, age, sex); } public Teacher(){} //教师的work实现是:教书育人,hello实现是:“同学好” @Override public void work() { System.out.println("教书育人"); } @Override public void hello() { System.out.println("同学好"); } } //定义子类Student class Student extends Person{ public Student(String name, int age, String sex) { super(name, age, sex); } //学生的work实现是:认真学习,hello实现是“老师好” @Override public void work() { System.out.println("认真学习"); } @Override public void hello() { System.out.println("老师好"); } }
3./*定义Shape抽象类,包含私有属性color,创建构造器为color赋值;包含计算周长的方法celPerimeter();定义子类Triangle,包含三边;定义子类Circle,包含半径radius;子类分别实现父类的计算周长功能。*/ //测试类 public class demo3{ public static void main(String[] args) { Shape a=new Triangle("红",2.9,1.4,3.4); System.out.println(a.celPerimeter()); Shape b=new Circle("黑",2.0); System.out.println(b.celPerimeter()); } } //定义Shape抽象类 public abstract class Shape{ //包含私有属性color,创建构造器为color赋值 private String color; public Shape() { } public Shape(String color) { this.color = color; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } //包含计算周长的方法celPerimeter() public abstract double celPerimeter(); } //定义子类Triangle,包含三边 public class Triangle extends Shape{ private double a1; private double a2; private double a3; public Triangle() { } public Triangle(String color, double a1, double a2, double a3) { super(color); this.a1 = a1; this.a2 = a2; this.a3 = a3; } public double getA1() { return a1; } public void setA1(double a1) { this.a1 = a1; } public double getA2() { return a2; } public void setA2(double a2) { this.a2 = a2; } public double getA3() { return a3; } public void setA3(double a3) { this.a3 = a3; } @Override public double celPerimeter() { return a1+a2+a3; } } //定义子类Circle,包含半径radius class Circle extends Shape{ private double radius; public Circle() { } public Circle(String color, double radius) { super(color); this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } @Override public double celPerimeter() { return 2*Math.PI*radius; } }
4.编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个 Employee对象的生日,则将该雇员的工资增加100元。 实验说明: (1)定义一个Employee类,该类包含: private成员变量name,number,birthday,其中birthday 为MyDate类的对象; abstract方法earnings(); toString()方法输出对象的name,number和birthday。 (2)MyDate类包含: private成员变量year,month,day ; toDateString()方法返回日期对应的字符串:xxxx年xx月xx日 (3)定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处 理。该类包括:private成员变量monthlySalary; 实现父类的抽象方法earnings(),该方法返回monthlySalary值;toString()方法输 出员工类型信息及员工的name,number,birthday。 (4)参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。该类包括: private成员变量wage和hour; 实现父类的抽象方法earnings(),该方法返回wage*hour值; toString()方法输出员工类型信息及员工的name,number,birthday。 (5)定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,以及该对象生日。当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。 /* 参考提示: //定义People类型的数组People c1[]=new People[10]; //数组元素赋值 c1[0]=new People("John","0001",20); c1[1]=new People("Bob","0002",19); //若People有两个子类Student和Officer,则数组元素赋值时,可以使父类类型的数组元素指向子类。 c1[0]=new Student("John","0001",20,85.0); c1[1]=new Officer("Bob","0002",19,90.5); */ import java.util.Scanner; //测试类 public class demo3{ public static void main(String[] args) { Scanner scanner =new Scanner(System.in); System.out.print("请输入月份: "); int month=scanner.nextInt(); //创建Employee变量数组并初始化 Employee[] employees= new Employee[2]; //该数组存放各类雇员对象的引用 employees[0] =new SalariedEmployee("Jack",1,new MyDate(2016,5,21),8888); employees[1] =new HourlyEmployee("Tom",2,new MyDate(2006,6,15),66,300); //利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,以及该对象生日 for (int i=0;i<employees.length;i++){ System.out.println(employees[i].toString()); double salary=employees[i].earnings(); System.out.println("月工资为: "+salary); // 当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。 if (month==employees[i].getBirthday().getMonth()){ double luncksalary=employees[i].earnings()+100; System.out.println("本月是:"+employees[i].getName()+"的生日,工资增加100元,总工资为:"+luncksalary); } } } } //)定义一个Employee类 public abstract class Employee{ //private成员变量name,number,birthday,其中birthday 为MyDate类的对象; private String name; private int number; private MyDate birthday; public Employee() { } public Employee(String name, int number, MyDate birthday) { this.name = name; this.number = number; this.birthday = birthday; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getNumber() { return number; } public void setNumber(int number) { this.number = number; } public MyDate getBirthday() { return birthday; } public void setBirthday(MyDate birthday) { this.birthday = birthday; } //abstract方法earnings(); public abstract double earnings(); //toString()方法输出对象的name,number和birthday public String toString(){ return "姓名:"+getName()+" 工资:"+getNumber()+" 生日:"+birthday.toDateString(); } } //MyDate类 class MyDate{ //private成员变量year,month,day private int year; private int month; private int day; public MyDate() { } public MyDate(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } //toDateString()方法返回日期对应的字符串:xxxx年xx月xx日 public String toDateString(){ return year+"年"+month+"月"+day+"日"; } } //定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处 public class SalariedEmployee extends Employee{ //该类包括:private成员变量monthlySalary private double monthlySalary; public SalariedEmployee() { } public SalariedEmployee(String name, int number, MyDate birthday, double monthlySalary) { super(name, number, birthday); this.monthlySalary = monthlySalary; } //toString()方法输出员工类型信息及员工的name,number,birthday。 @Override public String toString() { return "SalariedEmployee{" + super.toString() + '}'; } //实现父类的抽象方法earnings(),该方法返回monthlySalary值; @Override public double earnings() { return monthlySalary; } } //参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理 class HourlyEmployee extends Employee{ //private成员变量wage和hour private double wage; private double hour; public HourlyEmployee() { } public HourlyEmployee(String name, int number, MyDate birthday, double wage, double hour) { super(name, number, birthday); this.wage = wage; this.hour = hour; } public double getWage() { return wage; } public void setWage(double wage) { this.wage = wage; } public double getHour() { return hour; } public void setHour(double hour) { this.hour = hour; } //实现父类的抽象方法earnings(),该方法返回wage*hour值; @Override public double earnings() { return wage*hour; } //toString()方法输出员工类型信息及员工的name,number,birthday @Override public String toString() { return "HourlyEmployee{" + super.toString() + '}'; } }
5.定义一个接口用来实现两个对象的比较。 interface CompareObject{ public int compareTo(Object o); //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小 } 定义一个Circle类,`声明redius属性,提供getter和setter方法 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。 定义一个测试类InterfaceTest,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。 思 考 : 参 照 上 述 做 法 定 义 矩 形 类 Rectangle 和 ComparableRectangle 类 , 在 ComparableRectangle类中给出compareTo方法的实现,比较两个矩形的面积大小。
public class InterfaceTest { public static void main(String[] args) { CompareObject a1 = new ComparableCircle(2.0); CompareObject a2 = new ComparableCircle(3.0); int compare = a1.compareTo(a2); if (compare==0){ System.out.println("相等"); }else if (compare==1){ System.out.println("右边大"); }else { System.out.println("左边大"); } CompareObject b1 = new ComparableRectangle(2.0,3.0); CompareObject b2 = new ComparableRectangle(3.0,2.0); int compare1 = b1.compareTo(b2); if (compare1==0){ System.out.println("相等"); }else if (compare1==1){ System.out.println("右边大"); }else { System.out.println("左边大"); } } } public class Circle { private double radius; public Circle() { } public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } } class ComparableCircle extends Circle implements CompareObject{ public ComparableCircle(double radius) { super(radius); } public ComparableCircle() { } @Override public int compareTo(Object o) { if (this.getRadius() == ((Circle) o).getRadius()) { return 0; } else if (this.getRadius() < ((Circle) o).getRadius()) { return -1; } else { return 1; } } } public class Rectangle { private double len; private double wid; public Rectangle() { } public Rectangle(double len, double wid) { this.len = len; this.wid = wid; } public double getLen() { return len; } public void setLen(double len) { this.len = len; } public double getWid() { return wid; } public void setWid(double wid) { this.wid = wid; } public double s(){ return getLen()*getWid(); } } class ComparableRectangle extends Rectangle implements CompareObject{ public ComparableRectangle() { } public ComparableRectangle(double len, double wid) { super(len, wid); } @Override public int compareTo(Object o) { if (this.s() == ((Rectangle) o).s()) { return 0; } else if (this.s()< ((Rectangle) o).s()) { return -1; } else { return 1; } } }