专栏【Java基础题】
喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。
音乐分享【The truth that you leave】
大一同学小吉,欢迎并且感谢大家指出我的问题
目录
题目
代码
️Employee.class
️SalariedEmployee.class
️HourlyEmployee.class
️SalesEmployee.class
️BasePlusSalesEmployee.class
️Test.class
某公司的员工分为5类,每类员工都有相应的封装类,这5个类的信息如下。
(1) Employee:这是所有员工的父类。
1属性:员工的姓名、员工的生日月份。
2方法:getSalary(int month)根据参数月份确定工资。如果该月员工过生日,则公司会额外发放100元。
(2)SalariedEmployee:Employee的子类,拿固定工资的员工。
属性:月薪。
(3) HourlyEmployee:Employee的子类,按小时拿工资的员工,每月工作超出160h的部分按照1.5倍工资发放。
属性:每小时的工资、每月工作的小时数。
(4) SalesEmployee: Employee的子类,销售人员,工资由月销售额和提成率决定。属性:月销售额、提成率。
(5) BasePlusSalesEmployee:SalesEmployee的子类,有固定底薪的销售人员,工资为底薪加上销售提成。
属性:底薪。
本题要求根据上述员工分类,编写一个程序,实现以下功能:
(1)创建一个Employee数组,分别创建若干不同的Employee对象,并打印某个月的工资。
(2)每个类都完全封装,不允许有非私有化属性。
abstract class Employee{
private String name; //定义姓名name并私有化属性
private int month; //定义生日月份month并私有化属性
public Employee(){} //无参构造器
public Employee(String name,int month){ //有参构造方法
this.name = name; //给属性name初始化赋值
this.month = month; //给属性month初始化赋值
}
//获取属性name的方法
public String getName(){
return name; //返回name属性
}
//获取属性month的方法
public int getMonth(){
return month; //返回month属性
}
//给属性name赋初始值
public void setName(String name){
this.name = name; //本类中的属性name
}
//给属性month赋初始值
public void setMonth(int month){
this.month = month; //本类中的属性month
}
//创建一个方法getSalary()用来计算工资,参数month是月份,如果当月是员工生日,奖励100元
public double getSalary(int month){
double salary = 0; //定义工资变量
//判断当前月份是否是员 工的生日月份,如果是奖励100元
if(this.month == month){
salary = salary + 100;
return salary; //返回工资salary
}
}
}
class SalariedEmployee extends Employee{
private double monthSalary; //封装monthSalary属性
public SalariedEmployee(){} //无参构造方法
//有参构造方法 参数 姓名 生日月份 月薪
public SalariedEmployee(String name,int month,double monthSalary){
super(name,month); //调用父类有参构造方法
this.monthSalary = monthSalary; //为属性monthSalary初始化赋值
}
//获取monthSalary的值
public double getMonthSalary(){
return monthSalary;
}
//给monthSalary赋值
public void setMonthSalary(double monthSalary){
this.monthSalary = monthSalary;
}
//覆盖父类中的方法
public double getSalary(int month){
double salary = monthSalary+super.getSalary(month); //定义工资变量
return salary;
}
}
super.getSalary(),方法也能使用super
class HourlyEmployee extends Employee{
private double hourlySalary; //定义属性hourlySalary每小时的工资
private int hours; //定义属性hours每月工作的小时数
public HourlyEmployee(){} //无参构造方法
//有参构造方法 参数 姓名 生日月份 每小时的工资 每月工作的小时数
public HourlyEmployee(String name,int month,double hourlySalary,int hours){
super(name,month); //调用父类有参构造方法
this.hourlySalary = hourlySalary ; //为属性hourlySalary初始化赋值
this.hours = hours; //为属性hours 初始化赋值
}
public double getHourlySalary(){ //获取hourlySalary的值
return hourlySalary;
}
public int getHours(){ //获取hours的值
return hours;
}
//定义set方法设置hourlySalary hours的值
public void setHourlySalary(double hourlySalary){
this.hourlySalary =hourlySalary;
}
public void setHourly(int hours){
this.hours = hours;
}
//覆盖父类方法
public double getSalary(int month){
if(hours < 0){ //如果工作小时数小于0 输出数据错误
System.out.println("数据错误");
return 0;
}
//小于160个小时的 按照每个月的工作小时数乘以每小时的工资
else if(hours <= 160)
return hourlySalary*hours+super.getSalary(month);
//超出160个小时的小时数 按照1.5倍计算
else return hourlySalary*160+hourlySalary*1.5*(hours- 160)+super.getSalary(month);
}
}
class SalesEmployee extends Employee{
private double sales ; //定义销售额sales
private double rate; //定义提成率rate
public SalesEmployee(){}
public SalesEmployee(String name,int month,double sales,double rate){
super(name,month);
this.sales = sales;
this.rate = rate;
}
public double getSales(){
return sales;
}
public double getRate(){
return rate;
}
public void setSales(double sales){
this.sales = sales;
}
public void setRate(double rate){
this.rate = rate;
}
public double getSalary(int month){
return this.getSales()*(1+this.getRate())+super.getSalary(month);
}
}
class BasePlusSalesEmployee extends SalesEmployee{
private double baseSalary; //定义基础工资baseSalary
//无参构造方法
public BasePlusSalesEmployee(){}
//有参构造方法
public BasePlusSalesEmployee(String name,int month,double sales,double rate,double baseSalary){
super(name,month,sales,rate);
this.baseSalary = baseSalary;
}
//get/set方法对私有属性的调用和设置
public double gatBaseSalary(){
return baseSalary;
}
public void setBaseSalary(){
this.baseSalary = baseSalary;
}
public double getSalary(int month){
return baseSalary+super.getSalary(month);
}
}
注意使用super关键字
//定义一个测试类
public class Test{
public static void main(String[] args){
//声明一个Employee类型的数组,并创建不同子类型的对象
Employee[] employee = {new SalariedEmployee("张三",1,6000),new HourlyEmployee("李四",2,50,180),new SalesEmployee("王五",3,6500,0.15),new BasePlusSalesEmployee("赵六",4,5000,0.15,2000)};
//打印每个员工的工资
for(int i = 0; i < employee.length ;i++)
System.out.println(Math.round(employee[i].getSalary(10)));
}
}
注意这一段代码里面的数组的使用
1、Java语言中,什么是方法重载?
是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。调用这些同名的方法时,JVM会根据实际参数的不同绑定到不同的方法。
2、Java语言中,什么是方法重写?
在继承关系中,子类的方法与父类的某一方法具有相同的方法名、返回类型和参数列表,则称子类的该方法重写(覆盖)父类的方法
3、请简述Java语言中成员变量和局部变量的区别。
(1)、在类中的位置不同
成员变量:类中方法外。
局部变量:方法定义中或者方法声明上。
(2)、在内存中的位置不同
成员变量:在堆中。
局部变量:在栈中。
(3)、生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失。
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失。
(4)、初始化值不同
成员变量:有默认值。
局部变量:没有默认值,必须定义,赋值,然后才能使用。
4、请简述Java语言中构造方法的特点。
(1)、构造方法名与类名相同。
(2)、在构造方法名的前面没有返回值类型的声明。
(3)、在构造方法中不能使用return语句返回一个值。
5、构造方法和普通的成员方法有什么区别?
(1)、构造方法是类的一个特殊成员,它会在类实例化对象时被自动调用。而普通方法只有在使用的时候才会被调用。
(2)、在定义构造方法时要求方法名与类名相同、在方法名的前面没有返回值类型的声明、在方法中不能使用return语句返回一个值。
6、Java语言中,静态关键字static修饰的成员有哪些特点?
A:随着类的加载而加载 。
B:优先于对象存在。
C:被类的所有对象共享。
D:既可以通过对象名调用,也可以通过类名调用,建议通过类名调用。
7、Java语言中,静态变量和成员变量的区别有哪些?
A:所属不同
静态变量:属于类,称为类变量。
成员变量:属于对象,称为对象变量,实例变量。
B:内存位置不同
静态变量:方法区的静态区。
成员变量:堆内存。
C:生命周期不同
静态变量:静态变量是随着类的加载而加载,随着类的消失而消失。
成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失。
D:调用不同
静态变量:可以通过对象名调用,也可以通过类名调用。
成员变量:只能通过对象名调用。
8、Java语言中,成员变量和成员方法的访问修饰符有哪些?其访问权限如何?
public : 该类或非该类均可访问,不同包中的类也能访问。
protected: 相同包中的类可访问,不同包中的子类也能访问。
默认(缺省): 相同包中的类可访问,不同包中的类不能访问。
private: 只有本类可以访问,同一个或者不同包中的类不能访问。
9、Java语言中,this关键字的含义是什么?有哪些作用?
(1)、this关键字的含义:指代类对象本身
(2)、this 关键字的作用:
a:在定义类时如果方法参数或方法中定义的局部变量与类中的变量同名,可以通过this做前缀以示区别。
b:类中有多个重载的构造方法时,构造方法中可以通过this()调用本类的其他构造方法,但必须是构造方法中的第一条语句。
10、Java语言中,super关键字的含义是什么?有哪些作用?
(1)、super关键字的含义:指代父类对象引用(super代表父类存储空间的标识)。
(2)、super关键字的作用:
a:访问被子类隐藏的父类同名成员变量和成员方法 。
b:调用父类构造方法,且必须在子类构造方法的第一条代码。
11、Java语言中,abstract修饰符的特点有哪些?
(1)、abstract可修饰类和方法。
(2)、abstract修饰的类称为抽象类,不能被实例化。
(3)、抽象方法必须声明在抽象类中,且该方法不能有方法体。
(4)、抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。
.
12、Java语言中,final修饰符的特点有哪些?
(1)、final修饰的类称为最终类,不能被继承;
(2)、final修饰的方法称为最终方法,不能被覆盖(重写);
(3)、final修饰的变量是一个常量,不能被改写(重新赋值)。
13、Java语言中,多态的含义是什么?
多态就是使用父类类型的变量引用子类对象,根据被引用子类对象的不同特性,程序会得到不同的运行效果。
14、简要概述Java语言中break、continue、return语句的区别。
break:跳出单层循环。
continue:跳出一次循环,进入下一次的执行。
return:若有返回值,结束方法并返回一个值给调用者;若无返回值,结束方法的执行。
15、简要概述Java语言中实现多态的3个前提条件。
(1)、有子类继承父类或者实现类实现接口关系。
(2)、父子类之间或实现类与接口之间有方法重写。
(3)、有父类或者父接口引用指向子类对象。
16、简述Java语言中抽象类和接口的区别。
(1)、用abstract修饰的类称为抽象类。抽象类不能被实例化,需要定义一个子类来继承抽象类,子类对象可以赋值给抽象类引用变量。
(2)、接口是一种特殊的抽象类,接口中只能定义常量和抽象方法、默认方法以及静态方法。在定义接口时需要使用interface关键字。
17、简述Java语言中类与类,类与接口,接口与接口之间的关系。
(1)、类与类
继承关系,只能单继承,可以多层继承。
(2)、类与接口
实现关系,可以单实现,也可以多实现。
还可以在继承一个类的同时,实现多个接口。
(3)、接口与接口
继承关系,可以单继承,也可以多继承。
18、请简述@FunctionalInterface注解的作用。
该注解只是显示的标注了接口是一个函数式接口,并强制编辑器进行更严格的检查,确保该接口是函数式接口,如果不是函数式接口,那么编译器就会报错,而对程序运行并没有实质上的影响。
19、简述什么是方法引用与构造器引用。
Lambda表达式的主体只有一条语句时,程序不仅可以省略包含主体的花括号,还可以通过英文双冒号“::”的语法格式来引用方法和构造器(即构造方法),这两种形式可以进一步简化Lambda表达式的书写,其本质都是对Lambda表达式的主体部分已存在的方法进行直接引用,主要区别就是对普通方法与构造方法的引用而已。
20、Java语言中,编译期(受检)异常和运行期(非受检)异常的区别?
编译期异常:必须要处理的,否则编译不通过。
运行期异常:可以不处理,也可以处理。
21、Java语言中,throw和throws是的区别?
throws:
在方法声明上,后面跟的是异常的类名,可以是多个。
throws声明方法有异常,是一种可能性,这个异常并不一定会产生。
throw:
在方法体中,后面跟的是异常对象名,并且只能是一个。
throw抛出的是一个异常对象,说明这里肯定有一个异常产生了。
22、编译期异常的处理方案有几种,分别是什么?
有两种。
方式1:使用try…catch...finally语句对异常进行捕获处理。
方式2:使用throws关键字声明抛出异常,由调用者对抛出的异常进行处理。
23、Java语言中,运算符==和某个类中的equals()方法的区别是什么?
(1):==
基本类型:比较的是数值是否相同
引用类型:比较的是地址值是否相同
(2):equals()方法
只能比较引用类型。默认情况下,比较的是地址值是否相同。
但是,我们可以根据自己的需要重写该方法。
24、Java语言中,字符串的特点有哪些?
(1):字符串一旦被赋值,就不能改变。这里指的是字符串的内容不能改变,而不是引用不能改变。
(2):字符串直接赋值方式,其底层实现是:先去字符串常量池里面去找,如果有就直接返回,如果没有,就创建并返回。
(3):字面值作为字符串对象和通过构造方法创建对象的不同,前者会创建1个对象,后者创建2个对象。
25、Java语言中,String,StringBuffer,StringBuilder的区别?
(1):String是内容不可变的,而StringBuffer,StringBuilder都是内容可变的。
(2):StringBuffer是同步的,数据安全,效率低;StringBuilder是不同步的,数据不安全,效率高。
如果大家有不明白的地方,或者文章有问题,欢迎大家在评论区讨论,指正