1. 实验:利用IDE的debug功能给例6.4和例6.5的new语句设置断点,使用单步调试(step into/step over)跟踪子类对象实例化(初始化)的执行顺序,并总结该过程。
例6.4
public class SonAddClass extends AddClass {
private int a = 0, b = 0, c = 0;
SonAddClass(int x) {
super(x);
a = x + 7;
}
SonAddClass(int x, int y) {
super(x, y);
a = x + 5;
b = y + 5;
}
SonAddClass(int x, int y, int z) {
super(x, y, z);
a = x + 4;
b = y + 4;
c = z + 4;
}
public int add() {
System.out.println("supper: x + y + z = " + super.add());
return a + b + c;
}
public static void main(String[] args) {
SonAddClass p1 = new SonAddClass(2, 3, 5);
SonAddClass p2 = new SonAddClass(10, 20);
SonAddClass p3 = new SonAddClass(1);
System.out.println("a + b + c = " + p1.add());
System.out.println("a + b + c = " + p2.add());
System.out.println("a + b + c = " + p3.add());
}
}
class AddClass {
public int x = 0, y = 0, z = 0;
AddClass(int x) {
this.x = x;
}
AddClass(int x, int y) {
this(x);
this.y = y;
}
AddClass(int x, int y, int z) {
this(x, y);
this.z = z;
}
public int add() {
return x + y + z;
}
}
例6.6
public class Construct extends Pare {
private int i = 8;
Construct() {
}
Construct(int num) {
this();
}
int getSuper() {
return super.i;
}
public static void main(String[] args) {
Construct ct = new Construct(9);
System.out.println(ct.i);
System.out.println(ct.getSuper());
}
}
class Pare {
int i = 3;
Pare() {}
}
过程:
1.为子类对象分配内存空间,对域变量进行默认初始化。
2.绑定构造方法,将new对象中的参数传递给构造方法的形式参数。
3.调用this或super语句,二者只能存在一个。
4.进行实例变量的显式初始化操作。
5.执行当前构造方法体中的程序代码。
2. 如何实现两个对象之间互发消息,请举例说明。
在类中定义另一个类
class Client{
private Administrator a;
public void setA(A_a){
if(_a!=null){a=_a}
}
public Administrator getA(){
if(a!=null){return a}
else return null;
}
}
class Administrator{
Client c;
public A(Administrator aa){
this.a=aa;
aa.setA(this);
}
3. 谈谈组合与继承的区别以及两者的使用场景(即什么时候宜用组合 ?什么时候宜用继承?)。
区别:继承是子类共享父类中的部分方法和属性,组合是一个类把另一个类当作变量。
使用场景:
组合:需要保证类的安全性,不破坏封装,一个类只作为另一个类的数据成员。
继承:两个类有相同之处,子类可以使用父类的公有方法。
4. Java中的运行时多态的含义是什么?有什么作用?请举例说明。
同一个程序中出现同名的两个不同函数,即子类对父类的方法重写,就是多态。
使用父类引用指向子类实例,再调用父类中的方法时,不同子类会表现出不同结果。
5. 使用接口改写例6.8中的程序。
interface Shapes
{ public double getArea();
public double getPerimeter();
}
class Rect implements Shapes
{ private int k;
private int m;
public Rect(int k, int m){
this.k=m;
this.k=m;
}
public double getArea()
{ return(k*m); }
public double getPerimeter()
{ return(2*k+2*m);}
}
class Triangle implements Shapes
{ private int k;
private int x;
private int y;
public Triangle(int k, int x, int y){
this.k=k;
this.x=x;
this.y=y;
}
public double getArea()
{ double m=(x+y+z)/2.0;
return(Math.sqrt(m*( m-k)*( m-x)*(m-y)));}
public double getPerimeter()
{return(k+x+y);}
}
class Circle implements Shapes
{ private int m;
public Circle(int m){
this.m=m;
}
public double getArea()
{return(m* m *Math.PI);}
public double getPerimeter()
{return(2*Math.PI* m);}
}
public class RunShape extends Applet
{ Rect rect=new Rect(5,15,25,25);
Triangle tri=new Triangle(5,5,8);
Circle cir =new Circle(13,90,25);
public void paint(Graphics g)
{
g.drawRect(rect.x,rect.y,rect.k,(int)rect.m);
g.drawString("Rect Area:"+rect.getArea(),50,35);
g.drawString("Rect Perimeter:"+rect.getPerimeter(),50,55);
g.drawString("Triangle Area:"+tri.getArea(),50,75);
g.drawString("Triangle Perimeter:"+tri.getPerimeter(),50,95);
g.drawOval(cir.x-(int)cir.k/2,cir.y-(int)cir.k/2,cir.k,cir.k);
g.drawString("Circle Area:"+cir.getArea(),50,115);
g.drawString("Circle Perimeter:"+cir. getPerimeter(),50,135);
}
}
6. 自定义一个类,覆写equals方法,以满足自身业务需求
public class Student {
public String name[10];
public String sex;
public int age;
public int Class;
public static boolean equals(Object obj){
if(obj==null)
return false;
if(!(obj instanceof Student))
return false;
if(this==obj)
return true;
return sn.equals((Student)obj.sn);
}
}
7. 举例说明运算符instanceof的使用场景。
boolean x = s instanceof Person
当s是Person的实例化对象或者Person子类的实例化对象时,x的值为true,否则为false。
8. 谈谈抽象类与接口的异同以及两者的使用场景。
相同点:1、不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类还只能是抽象类。一个类实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
不同点:
一个类实现接口的话要实现接口的所有方法,而抽象类不用实现所有方法。
抽象类可以存在非final的变量,接口中声明的变量默认都是final的。
接口不能创建构造方法,抽象类可以创建构造方法。
类可以实现很多个接口,但是只能继承一个抽象类。
接口中的静态方法,只有接口可以进行调用,抽象类不一定。