面向对象特征之二:继承
为什么要有继承 多个类中存在相同属性和行为 时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
作用
继承的规则 说明
规则
子类不能直接访问父类中私有的(private)的成员变量和方法 。
Java只支持单继承,不允许多重继承
一个子类只能有一个父类
一个父类可以派生出多个子类
class SubDemo extends Demo{ } //ok
class SubDemo extends Demo1,Demo2...//error
练习 练习1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class ManKind { private int sex; private int salary; public int getSex () { return sex; } public void setSex (int sex) { this .sex = sex; } public int getSalary () { return salary; } public void setSalary (int salary) { this .salary = salary; } public void manOrWorman () { if (sex == 1 ){ System.out.println("man" ); } else if (sex == 0 ){ System.out.println("woman" ); } else System.out.println("输入有误!" ); } public void employeed () { if (salary == 0 ){ System.out.println("no job" ); } else if (salary != 0 ){ System.out.println("has job" ); } else System.out.println("输入有误!" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Kids extends ManKind { private int yearsOld; public int getYearsOld () { return yearsOld; } public void setYearsOld (int yearsOld) { this .yearsOld = yearsOld; } public void printAge () { System.out.println(yearsOld + " years old" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 public class TestKids { public static void main (String[] args) { Kids someKid = new Kids(); someKid.setSex(1 ); someKid.setSalary(50000 ); someKid.setYearsOld(22 ); someKid.manOrWorman(); someKid.employeed(); someKid.printAge(); } }
练习2: 根据下图实现类。在TestCylinder类中创建Cylinder类的对象,设置圆柱的底面半径和高,并输出圆柱的体积。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Circle { private double radius; public Circle () { this .radius = 1 ; } public double getRadius () { return radius; } public void setRadius (double radius) { this .radius = radius; } public double findArea () { return Math.PI * radius * radius; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Cylinder extends Circle { private double length; public Cylinder () { this .length = 1 ; } public double getLength () { return length; } public void setLength (double length) { this .length = length; } public double findVolume () { return findArea() * length; } }
1 2 3 4 5 6 7 8 public class TestCylinder { public static void main (String[] args) { Cylinder cylinder= new Cylinder(); cylinder.setRadius(2 ); cylinder.setLength(4 ); System.out.println("圆柱的体积为:" + cylinder.findVolume()); } }
方法的重写:override 定义 在子类中可以根据需要对从父类中继承来的方法进行改造 ,也称方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法 。
要求
四种访问权限修饰符 Java权限修饰符public、protected、private 置于类的成员 定义前,用来限定对象对该类对象成员的访问权限。
对于class的权限修饰只可以用public和default
public类可以在任意地方被访问。
default类只可以被同一个包内部的类访问。
关键字—super 作用
调用父类的构造器
子类中所有的构造器默认 都会访问父类中空参数 的构造器
当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)
或者super(参数列表)
语句指定调用本类或者父类中相应的构造器,且必须放在构造器的第一行
如果子类构造器中既未显式调用父类或本类的构造器,默认调用的是父类空参的构造器 ,如果父类中又没有无参的构造器,则编译出错
this和super的区别
子类对象的实例化过程
练习:类的继承,super
写一个名为Account的类模拟账户。该类的属性和方法如下图所示。该类包括的属性:账号id,余额balance,年利率annualInterestRate;包含的方法:访问器方法(getter和setter方法),返回月利率的方法getMonthlyInterest()
,取款方法withdraw()
,存款方法deposit()
。
提示: 在提款方法withdraw中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应给出提示。
测试: 写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象。使用withdraw方法提款30000元,并打印余额。再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。
运行结果如图所示:
创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。在CheckAccount类中重写withdraw方法,其算法如下:
1 2 3 4 5 6 7 8 9 如果(取款金额<账户余额), 可直接取款 如果(取款金额>账户余额), 计算需要透支的额度 判断可透支额overdraft是否足够支付本次透支需要 如果可以 将账户余额修改为0,冲减可透支金额 如果不可以 提示用户超过可透支额的限额
提示: (1)子类CheckAccount的构造方法需要将从父类继承的3个属性和子类自己的属性全部初始化。(2)父类Account的属性balance被设置为private,但在子类CheckAccount的withdraw方法中需要修改它的值,因此应修改父类的balance属性,定义其为protected。
要求: 写一个用户程序测试CheckAccount类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。使用withdraw方法提款5000元,并打印账户余额和可透支额。再使用withdraw方法提款18000元,并打印账户余额和可透支额。再使用withdraw方法提款3000元,并打印账户余额和可透支额。
运行结果如下图所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 public class Account { protected int id; protected double balance; protected double annualInterestRate; public Account (int id, double balance, double annualInterestRate) { super (); this .id = id; this .balance = balance; this .annualInterestRate = annualInterestRate; } public int getId () { return id; } public void setId (int id) { this .id = id; } public double getBalance () { return balance; } public void setBalance (double balance) { this .balance = balance; } public double getAnnualInterestRate () { return annualInterestRate; } public void setAnnualInterestRate (double annualInterestRate) { this .annualInterestRate = annualInterestRate; } public double getMonthlyInterest () { return this .annualInterestRate/12 ; } public void withdraw (double amount) { if (balance >= amount){ balance -= amount; }else { System.out.println("余额不足!" ); } } public void deposit (double amount) { balance += amount; }
1 2 3 4 5 6 7 8 9 10 11 public class TestAccount { public static void main (String[] args) { Account account = new Account(1122 ,20000 ,0.045 ); account.withdraw(30000 ); System.out.println("您的账户余额为:" + account.getBalance()); account.withdraw(2500 ); account.deposit(3000 ); System.out.println("您的账户余额为:" + account.getBalance()); System.out.println("月利率为:" + account.getMonthlyInterest()); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class CheckAccount extends Account { private double overdraft; public CheckAccount (int id, double balance, double annualInterestRate, double overdraft) { super (id, balance, annualInterestRate); this .overdraft = overdraft; } public double getOverdraft () { return overdraft; } public void setOverdraft (double overdraft) { this .overdraft = overdraft; } public void withdraw (double amount) { if (amount <= balance){ balance -= amount; } else { if (amount - balance <= overdraft){ overdraft -= (amount - balance); balance = 0 ; } else { System.out.println("超过可透支额的限额!" ); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class TestCheckAccount { public static void main (String[] args) { CheckAccount checkAccount = new CheckAccount(1122 ,20000 ,0.045 ,5000 ); checkAccount.withdraw(5000 ); System.out.println("您的账户余额:" + checkAccount.getBalance()); System.out.println("您的可透支额:" + checkAccount.getOverdraft()); checkAccount.withdraw(18000 ); System.out.println("您的账户余额:" + checkAccount.getBalance()); System.out.println("您的可透支额:" + checkAccount.getOverdraft()); checkAccount.withdraw(3000 ); System.out.println("您的账户余额:" + checkAccount.getBalance()); System.out.println("您的可透支额:" + checkAccount.getOverdraft()); } }
面向对象特征之三:多态性 基本概念 可以理解为:一个事物的多种表现形态~
多态性,是面向对象中最重要的概念,在java中有两种体现:
方法的重载(overload)和重写(overwrite)。
对象的多态性 ——可以直接应用在抽象类和接口上。
引用变量类型
Java引用变量有两个类型:编译时类型 和运行时类型 。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。
若编译时类型和运行时类型不一致,就出现多态(Polymorphism)
对象的多态
对象的多态 —在Java中,子类的对象可以替代父类的对象使用
一个变量只能有一种确定的数据类型
一个引用类型变量可能指向(引用)多种不同类型的对象
1 2 3 Person p = new Student(); Object o = new Person(); o = new Student();
1 2 3 4 5 Student m = new Student(); m.school = “pku”; Person e = new Student(); e.school = “pku”;
虚拟方法调用(Virtual Method Invocation) 正常的方法调用 1 2 3 4 Person e = new Person(); e.getInfo(); Student e = new Student(); e.getInfo();
虚拟方法调用(多态情况下) 1 2 Person e = new Student(); e.getInfo();
编译时类型和运行时类型 编译时e为Person类型,而方法的调用是在运行时确定的, 所以调用的是Student类的getInfo()方法。——动态绑定
小结 前提
成员方法
编译时 :要查看引用变量所属的类中是否有所调用的方法。
运行时 :调用实际对象所属的类中的重写方法。
成员变量
子类继承父类
若子类重写了父类方法 ,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中
对于实例变量 则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖 父类中定义的实例变量
instanceof 操作符 x instanceof A
:检验对象x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
练习 练习1 :建立 TestInstance 类,在类中定义方法 method1(Person e);
在method1中:
根据e的类型调用相应类的getInfo()
方法。
根据e的类型执行:
如果e为Person类的对象,输出:
如果e为Student类的对象,输出:
如果e为Graduate类的对象,输出:
1 2 3 a graduated student a student a person
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public class TestInstance { public static void main (String[] args) { TestInstance t = new TestInstance(); t.method1(new Student()); System.out.println(); t.method1(new Graduate()); } public void method1 (Person p) { System.out.println(p.getInfo()); if (p instanceof Graduate){ System.out.println("a graduated student" ); } if (p instanceof Student){ System.out.println("a a student" ); } if (p instanceof Person){ System.out.println("a person" ); } } } class Person { protected String name="person" ; protected int age=50 ; public String getInfo () { return "Name: " + name + "\n" +"age: " + age; } } class Student extends Person { protected String school="heu" ; public String getInfo () { return "Name: " + name + "\nage: " + age + "\nschool: " + school; } } class Graduate extends Student { public String major="IT" ; public String getInfo () { return "Name: " + name + "\nage: " + age + "\nschool: " + school+"\nmajor:" +major; } }
练习2 :多态—动态绑定
定义三个类,父类 GeometricObject 代表几何形状,子类 Circle 代表圆形,MyRectangle代表矩形。
定义一个测试类Test,编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class GeometricObject { protected String color; protected double weight; protected GeometricObject (String color, double weight) { this .color = color; this .weight = weight; } public String getColor () { return color; } public void setColor (String color) { this .color = color; } public double getWeight () { return weight; } public void setWeight (double weight) { this .weight = weight; } public double findArea () { return 0.0 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class Circle extends GeometricObject { private double radius; public Circle (double radius, String color, double weight) { super (color, weight); this .radius = radius; } public double getRadius () { return radius; } public void setRadius (double radius) { this .radius = radius; } public double findArea () { return Math.PI * radius * radius; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class MyRectangle extends GeometricObject { private double width; private double height; public MyRectangle (double width, double height, String color, double weight) { super (color, weight); this .width = width; this .height = height; } public double getWidth () { return width; } public void setWidth (double width) { this .width = width; } public double getHeight () { return height; } public void setHeight (double height) { this .height = height; } public double findArea () { return width * height; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class Test { public static void main (String[] args) { Test test = new Test(); Circle circle1 = new Circle(2.3 , "Green" , 1.0 ); Circle circle2 = new Circle(2.3 , "Red" , 1.0 ); MyRectangle myRectangle = new MyRectangle(2.3 , 3.0 , "blue" , 2.0 ); test.displayGeometricObject(circle1); boolean b = test.equalsArea(circle1,circle2); System.out.println(b); } public boolean equalsArea (GeometricObject g1, GeometricObject g2) { return g1.findArea() == g2.findArea(); } public void displayGeometricObject (GeometricObject g) { System.out.println(g.findArea()); } }
对象类型转换(Casting)
基本数据类型的Casting:
自动类型转换:小的数据类型可以自动转换成大的数据类型。如long g=20; double d=12.0f
强制类型转换:可以把大的数据类型强制转换(casting)成小的数据类型。如 float f=(float)12.0; int a=(int)1200L
对Java对象的强制类型转换称为造型
从子类到父类的类型转换可以自动进行
从父类到子类的类型转换必须通过造型(强制类型转换)实现
无继承关系的引用类型间的转换是非法的
在造型前可以使用instanceof操作符测试一个对象的类型
Object类 Object类是所有Java类的根父类
如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类
1 2 3 4 5 6 7 8 9 10 11 public class Person { ... } 等价于: public class Person extends Object {... } 例:method(Object obj){…} Person o=new Person(); method(o);
Object类中的主要方法
==操作符与equals方法 ==操作符
用“==”进行比较时,符号两边的数据类型必须兼容 (可自动转换的基本数据类型除外),否则编译出错。
equals方法 所有类都继承了Object,也就获得了equals()方法,还可以重写。
练习 练习1: 编写Order类,有int型的orderId,String型的OrderName,相应的getter()和setter()方法,两个参数的构造器,重写父类的equals()方法:public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public class TestOrder { public static void main (String[] args) { Order o1 = new Order(1001 ,"AA" ); Order o2 = new Order(1001 ,"AA" ); System.out.println(o1 == o2); System.out.println(o1.equals(o2)); } } class Order { private int orderId; private String orderName; public Order (int orderId, String orderName) { super (); this .orderId = orderId; this .orderName = orderName; } public int getOrderId () { return orderId; } public void setOrderId (int orderId) { this .orderId = orderId; } public String getOrderName () { return orderName; } public void setOrderName (String orderName) { this .orderName = orderName; } public boolean equals (Object obj) { if (this == obj){ return true ; } else if (obj instanceof Order){ Order o1 = (Order) obj; return this .orderId == o1.orderId && this .orderName.equals(o1.orderName); } else return false ; } }
练习2: 请根据以下代码自行定义能满足需要的MyDate类,在MyDate类中覆盖equals方法,使其判断当两个MyDate类型对象的年月日都相同时,结果为true,否则为false。 public boolean equals(Object o)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class TestEquals { public static void main (String[] args) { MyDate m1 = new MyDate(14 , 3 , 1976 ); MyDate m2 = new MyDate(14 , 3 , 1976 ); if ( m1 == m2 ) { System.out.println("m1==m2" ); } else { System.out.println("m1!=m2" ); } if ( m1.equals(m2) ) { System.out.println("m1 is equal to m2" ); } else { System.out.println("m1 is not equal to m2" ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 public class TestMyDate { public static void main (String[] args) { MyDate m1 = new MyDate(14 , 3 , 1976 ); MyDate m2 = new MyDate(14 , 3 , 1976 ); if ( m1 == m2 ) { System.out.println("m1==m2" ); } else { System.out.println("m1!=m2" ); } if ( m1.equals(m2) ) { System.out.println("m1 is equal to m2" ); } else { System.out.println("m1 is not equal to m2" ); } } } class MyDate { private int day; private int month; private int year; public MyDate (int day, int month, int year) { super (); this .day = day; this .month = month; this .year = year; } public int getDay () { return day; } public void setDay (int day) { this .day = day; } public int getMonth () { return month; } public void setMonth (int month) { this .month = month; } public int getYear () { return year; } public void setYear (int year) { this .year = year; } public boolean equals (Object o) { if (this == o){ return true ; } else if (o instanceof MyDate){ MyDate myDate = (MyDate) o; return this .day == myDate.day && this .month == myDate.month && this .year == myDate.year; } else return false ; } }
toString()方法
1 2 3 Date now=new Date(); System.out.println(“now=” + now); System.out.println(“now=” + now.toString());
可以根据需要在用户自定义类型中重写toString()方法。如String类重写了toString()方法,返回字符串的值 。
1 2 3 s1=“hello”; System.out.println(s1); System.out.println(s1.toString());
基本类型数据转换为String类型时,调用了对应包装类的toString()方法
1 2 int a=10 ; System.out.println(“a=” + a);
练习 练习: 定义两个类,父类GeometricObject代表几何形状,子类Circle代表圆形。
写一个测试类,创建两个Circle对象,判断其颜色是否相等;利用equals方法判断其半径是否相等;利用toString()方法输出其半径。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class GeometricObject { protected String color; protected double weight; public GeometricObject () { super (); this .color = "white" ; this .weight = 1.0 ; } public GeometricObject (String color, double weight) { super (); this .color = color; this .weight = weight; } public String getColor () { return color; } public void setColor (String color) { this .color = color; } public double getWeight () { return weight; } public void setWeight (double weight) { this .weight = weight; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class Circle extends GeometricObject { private double radius; public Circle () { this .radius = 1.0 ; } public Circle (double radius) { this .radius = radius; } public Circle (double radius,String color,double weight) { super (color, weight); this .radius = radius; } public double getRadius () { return radius; } public void setRadius (double radius) { this .radius = radius; } public double findArea () { return 3.14 * radius * radius; } public boolean equals (Object obj) { if (obj == this ){ return true ; } else if (obj instanceof Circle){ Circle c1 = (Circle) obj; return this .radius == c1.radius; } else return false ; } public String toString () { return String.valueOf(radius); } }
1 2 3 4 5 6 7 8 9 public class TestCircle { public static void main (String[] args) { Circle circle1 = new Circle(2.3 ); Circle circle2 = new Circle(2.3 ); System.out.println(circle1.color == circle2.color); System.out.println(circle1.equals(circle2)); System.out.println(circle1.toString()); } }
包装类(Wrapper)
针对八种基本定义相应的引用类型—包装类(封装类)
有了类的特点,就可以调用类中的方法。
基本数据类型和包装类之间的转换
基本数据类型包装成包装类的实例 — 装箱
通过包装类的构造器实现: int i = 500; Integer t = new Integer(i);
还可以通过字符串参数构造包装类对象:
1 2 Float f = new Float(“4.56 ”); Long l = new Long(“asdf”);
1 2 3 4 Integer a = 10 ; Boolean b = false ; int b = a;
与String类之间的转换 基本数据类型转换成字符串
字符串转换成基本数据类型
包装类转换成字符串
练习 练习: 利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。而向量类java.util.Vector可以根据需要动态伸缩 。
创建Vector对象:Vector v=new Vector();
给向量添加元素:v.addElement(obj);
//obj必须是对象
取出向量中的元素:Object obj=v.elementAt(0);
注意第一个元素的下标是0,返回值是Object类型的。
计算向量的长度:v.size();
若与最高分相差10分内:A等;20分内:B等;30分内:C等;其它:D等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package L04.exer8;import java.util.Scanner;import java.util.Vector;public class TestScore { public static void main (String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入学生的成绩:(以负数代表输入结束)" ); Vector v = new Vector(); int maxScore = 0 ; for (;;){ int score = scanner.nextInt(); if (score < 0 ){ break ; } if (maxScore < score){ maxScore = score; } v.addElement(score); } for (int i = 0 ; i < v.size(); i++){ Integer score = (Integer) v.elementAt(i); char level; if (maxScore - score <= 10 ){ level = 'A' ; }else if (maxScore - score <= 20 ){ level = 'B' ; }else if (maxScore - score <= 30 ){ level = 'C' ; }else level = 'D' ; System.out.println("学生成绩为:" + score + " 等级为:" + level); } } }
面试题
我比较两个String总是false,但是它们明明都是”abc” ! 答:比较String一定要使用equals或equalsIgnoreCase方法,不要使用 == ! ==比较的是两个引用(变量)是否指向了同一个对象,而不是比较其内容。
int 和 Integer 有什么区别 答:Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。 Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型封装类,booleanBoolean,charCharacter,byteByte,shortShort,intInteger,longLong,floatFloat,doubleDouble 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。 引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class A { int a=1 ; double d=2.0 ; void show () { System.out.println("Class A: a=" +a +"\td=" +d); } } class B extends A { float a=3.0f ; String d="Java program." ; void show () { super .show( ); System.out.println("Class B: a=" +a +"\td=" +d); } } (1 ) 若在应用程序的main方法中有以下语句: A a=new A(); a.show(); 则输出的结果如何? (2 ) 若在应用程序的main方法中定义类B的对象b: A b=new B(); b.show(); 则输出的结果如何? 答:输出结果为: 1 )Class A: a=1 d=2.0 2 )Class A: a=1 d=2.0 Class B: a=3.0 d=Java program。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public void testString () { String str1 = "小狗" ; String str2 = "小狗" ; String str3 = new String("小狗" ); System.out.println(str1 == str2); System.out.println(str1 == str3); System.out.println(str1.equals(str3)); str1 = "小猫" ; String str4 = "吃鱼" ; String str5 = "小猫" + "吃鱼" ; System.out.println(str1 == str5); String str6 = (str2 + str4).intern(); System.out.println(str1 == str6); }
重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?Overload的方法是否可以改变返回值的类型? 答:方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被”屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Test { Test() { System.out.println("Test" ); } } class Demo extends Test { Demo() { System.out.println("Demo" ); } public static void main (String[] args) { new Demo(); new Test(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class A { private int a; public void setA (int a) { this .a = a; } public int getA () { return a; } } class B extends A { private int a; public void setA (int a) { this .a = a; } } public class TestPerson { public static void main (String[] args) { A c = new B(); c.setA(5 ); System.out.println(c.getA()); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Fu { boolean show (char a) { System.out.println(a); return true ; } } class Demo extends Fu { public static void main (String[] args) { int i=0 ; Fu f=new Demo(); Demo d=new Demo(); for (f.show('A' ); f.show('B' )&&(i<2 );f.show('C' )) { i++; d.show('D' ); } } boolean show (char a) { System.out.println(a); return false ; } } A B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Super { int i=0 ; public Super (String a) { System.out.println("A" ); i=1 ; } public Super () { System.out.println("B" ); i+=2 ; } } class Demo extends Super { public Demo (String a) { System.out.println("C" ); i=5 ; } public static void main (String[] args) { int i=4 ; Super d=new Demo("A" ); System.out.println(d.i); } } B C 5
选择题,写出错误答案错误的原因,用单行注释的方式。
1 2 3 4 class Demo { int show (int a,int b) {return 0 ;} }
下面那些函数可以存在于Demo的子类中。 A. public int show(int a,int b){return 0;} //可以,覆盖。 B. private int show(int a,int b){return 0;} //不可以,权限不够。 C. private int show(int a,long b){return 0;} //可以,和父类不是一个函数。没有覆盖,相当于重载。 D. public short show(int a,int b){return 0;} //不可以,因为该函数不可以和给定函数出现在同一类中,或者子父类中。 E. static int show(int a,int b){return 0;} //不可以,静态只能覆盖静态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Fu { int num=4 ; void show () { System.out.println("showFu" ); } } class Zi extends Fu { int num=5 ; void show () { System.out.println("showZi" ); } } class T { public static void main (String[] args) { Fu f=new Zi(); Zi z=new Zi(); System.out.println(f.num); System.out.println(z.num); f.show(); z.show(); } } 4 5 showZi showZi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Super { int i=0 ; public Super (String s) { i=1 ; } } class Demo extends Super { public Demo (String s) { i=2 ; } public static void main (String[] args) { Demo d=new Demo("yes" ); System.out.println(d.i); } }
//编译失败,因为父类中缺少空参数的构造函数。 //或者子类应该通过super语句指定要调用的父类中的构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 class Super { public int get () {return 4 ;} } class Demo15 extends Super { public long get () {return 5 ;} public static void main (String[] args) { Super s=new Demo15(); System.out.println(s.get()); } }
//编译失败,因为子类父类中的get方法没有覆盖。但是子类调用时候不能明确返回的值是什么类型。所以这样的函数不可以存在子父类中。
继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package test;public class FatherClass { public FatherClass () { System.out.println("FatherClass Create" ); } } package test;import test.FatherClass;public class ChildClass extends FatherClass { public ChildClass () { System.out.println("ChildClass Create" ); } public static void main (String[] args) { FatherClass fc = new FatherClass(); ChildClass cc = new ChildClass(); } }
当执行如下操作 C:>java test.ChildClass 输出结果为: FatherClass Create FatherClass Create ChildClass Create
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class OuterClass { private double d1 = 1.0 ; } You need to insert an inner class declaration at line 3. Which two inner class declarations are valid ?(Choose two .) A . class InnerOne { public static double methoda () {return d1;} } B. public class InnerOne { static double methoda () {return d1;} } C. private class InnerOne { double methoda () {return d1;} } D. static class InnerOne { protected double methoda () {return d1;} } E. abstract class InnerOne { public abstract double methoda () ; }
说明如下: 一.静态内部类可以有静态成员,而非静态内部类则不能有静态成员。 故 A、B 错 二.静态内部类的非静态成员可以访问外部类的静态变量,而不可访问外部类的非静态变量;return d1 出错。 故 D 错 三.非静态内部类的非静态成员可以访问外部类的非静态变量。 故 C 正确 四.答案为C、E
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Test { int x= 12 ; public void method (int x) { x+=x; System.out.println(x); } } Given: Test t = new Test(); t.method(5 ); What is the output from line 5 of the Test class ? A . 5//B . 10 C . 12D . 17E . 24