java基础题(3)
5.面向对象
5.1封装
5.1.1修改Data类的定义
描述
现有一个Data类,内部定义了属性x和y,在main方法中实例化了Data类,并计算了data对象中x和y的和。但是,Data类的定义存在错误,请你将这些错误修正过来,使得main方法中的求和逻辑可以正常执行。
输入描述:
两个整数
输出描述:
两个整数的和
示例1
输入:1 2; 输出:3
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNextInt()) { int x = scanner.nextInt(); int y = scanner.nextInt(); Data data = new Data(x, y); System.out.println(data.getX() + data.getY()); } } //创建内部类和构造方法 static class Data{ private int x; private int y; public Data(int x, int y) { this.x = x; this.y = y; } private int getX() { return x; } private int getY() { return y; } } }
5.1.2验证年龄
描述
采用封装的思想,为Person类定义年龄属性,要求:
修改年龄时判断其范围,若年龄小于0则按0输出,若年龄大于200则按200输出。
输入描述:
年龄整数值
输出描述:
1. 若年龄小于0则输出0;
2. 若年龄大于200则输出200;
3. 若年龄介于[0,200]之间则直接输出。
import java.util.Scanner; public class Main { public static void main(String[] args) { Person p = new Person(); Scanner scanner = new Scanner(System.in); while (scanner.hasNextInt()) { int age = scanner.nextInt(); p.setAge(age); System.out.println(p.getAge()); } } } class Person { private int age; //write your code here...... public int getAge() { return age; } public void setAge(int age) { if (age >200 ) { this.age = 200; } else if (age >= 0 && age <= 200) { this.age = age; } else if(age <0) { this.age = 0; } } }
5.2继承
5.2.1补全构造方法
描述:
有父类Base,内部定义了x、y属性。有子类Sub,继承自父类Base。子类新增了一个z属性,并且定义了calculate方法,在此方法内计算了父类和子类中x、y、z属性三者的乘积。请补全子类构造方法的初始化逻辑,使得该计算逻辑能够正确执行。
输入描述:
三个整数:x, y, z
输出描述:
三个整数的乘积:x*y*z
示例1
输入:1 2 3; 输出:6
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNextInt()) { int x = scanner.nextInt(); int y = scanner.nextInt(); int z = scanner.nextInt(); Sub sub = new Sub(x, y, z); System.out.println(sub.calculate()); } } } class Base { private int x; private int y; public Base(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } } class Sub extends Base { private int z; public Sub(int x, int y, int z) { //write your code here super(x,y); this.z=z; } public int getZ() { return z; } public int calculate() { return super.getX() * super.getY() * this.getZ(); } }
5.2.2重写计算逻辑
描述
在父类Base中定义了计算方法calculate(),该方法用于计算两个数的乘积(X*Y)。请在子类Sub中重写该方法,将计算逻辑由乘法改为除法(X/Y)。注意,当分母为0时输出“Error”。
输入描述:
两个整数
输出描述:
两个整数的商(int类型,不考虑小数情况)
示例1
输入:6 2 输出:3
示例2
输入:1 0
输出:error
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNextInt()) { int x = scanner.nextInt(); int y = scanner.nextInt(); Sub sub = new Sub(x, y); sub.calculate(); } } } class Base { private int x; private int y; public Base(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } public void calculate() { System.out.println(getX() * getY()); } } class Sub extends Base { //write your code here...... public Sub(int x, int y){ //父类的构造方法 super(x, y); } public void calculate(){ if(getY() == 0) //除数为0 System.out.println("Error"); else System.out.println(getX() / getY()); } }
5.3多态
5.3.1定义打印方法
描述
已知有三个类:First、Second、Third。要求定义一个打印方法,支持传入任意引用类型的参数(包括上述三个类),并在方法内部打印出对象的字符串形式。
输入描述:
类名
输出描述:
由该类实例化出来的对象的字符串表示
示例1
输入:First 输出:First
import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String className = scanner.next(); // print就是需要你定义的方法 print(Class.forName(className).newInstance()); } } //write your code here...... public static void print(Object obj){ System.out.println(obj.getClass().getName()); } } class First { public String toString() { return "First"; } } class Second { public String toString() { return "Second"; } } class Third { public String toString() { return "Third"; } }
5.3.2类型判断
描述
父类Base有两个子类:Sub1、Sub2,现有一个方法getClassName(),要求传入Base类型的实例,在方法内部判定其具体的类型,返回的是类型的简单名字(不含包名),请补全getClassName()方法的判断逻辑。
输入描述:
输入要实例化的类名:Base、Sub1、Sub2 三者之一。
输出描述:
返回实例的实际类名(简化类名,不包含包的名字)。
import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String className = scanner.next(); Base obj = (Base) Class.forName(className).newInstance(); System.out.println(getClassName(obj)); } } public static String getClassName(Base obj) { //write your code here...... if (obj instanceof Sub1) { Sub1 sub1 = (Sub1) obj; return sub1.getClass().getSimpleName(); } else if (obj instanceof Sub2) { Sub2 sub2 = (Sub2) obj; return sub2.getClass().getSimpleName(); } else { return obj.getClass().getSimpleName(); } } } class Base { } class Sub1 extends Base { } class Sub2 extends Base { }
此处:通过instanceof运算符判断obj是否属于右边类所创建对象,instanceof是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回值为boolean类型。若返回结果为true,若是则调用调用Object的getClass()方法获得Class对象,之后用getSimpleName()方法来获取这个类的名称(此环境下使用getName()方法也可以获得正确结果,但在常规情况下,使用getName()会返回包括包名在内的实体名称,这里需要注意)
注解:instanceof 该运算符是二目运算符,左边的操作元是一个对象,右边是一个类,当左边的对象是右边的类或子类创建的对象时,该运算符运算的结果是true,否则是false。