Java学习记录-5(面向对象3)

1. 实验:利用IDE的debug功能给代码中的new语句设置断点,使用单步调试(step into/step over)跟踪子类对象实例化(初始化)的执行顺序,并总结该过程。

  1. 为对象分配内存空间,对成员变量进行默认的初始化
  2. 绑定构造方法,将new中的参数传递给构造方法的形式参数。
  3. 调用this或super语句(二者必居其一,不能同时存在),执行流程如图所示
  4. 进行实例变量的显式初始化操作, 如:
public class A{
	int value=4;       //显式初始化
	B b = new B();   //显式初始化,注:B为另一个类
}
  1. 执行当前构造方法的方法体中的程序代码。
    在这里插入图片描述

2. 如何实现两个对象之间互发消息,请举例说明。

  1. 引用必须真实引用了特定的对象,否则会在运行时抛出NullPointerException异常。
  2. 被访问对象必须定义了相应的属性或方法,否则编译不会通过。
  3. 被访问的属性或方法必须具有可访问的权限。
class FighterPlane {
   private String name;
   private int missileNum;   
   private A  a;

   public void setA(A _a){
      if (_a !=null)  { a = _a ;}
   }

   public A getA(){
      if (a !=null)
          { return a;}
      else  return null;
   }

   public void fire(){ ……}
   public FighterPlane(String _name,int _missileNum){ ……}
}
class A 
{
    FighterPlane fp;
    public A(FighterPlane fpp){
       this.fp = fpp; 
       fpp.setA(this);//将当前对象传给FighterPlane
    }
    public void invoke(){
       //A中对象发送消息给FighterPlane的对象
       fp.fire(); 
    }
}
public class Run{
   public static void main(String[] args)
   {  
     FighterPlane ftp = new FighterPlane("su35",10);
     A  a   = new A(ftp); 
     a.invoke(); }
}

3. 谈谈组合与继承的区别以及两者的使用场景。

  • 组合:在新类里面创建原有类的对象,重复利用已有类的功能。(has-a关系)
/**
*继承
*/
class Vehicle{}
class Car entends Vehicle{}
  • 继承:可以使用现有类的功能,并且在无需重复编写原有类的情况下对原有类进行功能上的扩展。(is-a关系)
/**
*组合
*/
class Tire{}
class Car entends Vehicle{
	private Tire t = new Tire();
}
  • 使用场景:
    • 除非两个类之间是“is-a”的关系,否则不要轻易的使用继承,不要单纯的为了实现代码的重用而使用继承,因为过多的使用继承会破坏代码的可维护性,当父类被修改时,会影响到所有继承自它的子类,从而增加程序的维护难度和成本。
    • 不要仅仅为了实现多态而使用继承,如果类之间没有“is-a”的关系,可以通过实现接口与组合的方式来达到相同的目的。设计模式中的策略模式可以很好的说明这一点,采用接口与组合的方式比采用继承的方式具有更好的可扩展性。
    • 在Java语言中,能使用组合就尽量不要使用继承。

4. Java中的运行时多态的含义是什么?有什么作用?请举例说明。

  • 含义:程序运行时,Java从实例所属的类(new 类)开始寻找匹配的方法执行,如果当前类中没有匹配的方法,则沿着继承关系逐层向上,依次在父类或各祖先类中寻找匹配方法,直到Object类。
  • 作用:动态绑定,使用父类引用指向子类对象,再调用某一父类中的方法时,不同子类会表现出不同结果,扩展性极好
    public class Test {
 
    public static void main(String[] args) {
        //运行时多态
        Father c = new SonClass();
        c.method();   //父类的构造方法 子类的构造方法 子类的method()
        c.method2();  //父类的构造方法 子类的构造方法 父类的method2()
    }
}
 
class Father {
 
 
    public Father() {
        System.out.print("父类的构造方法\t");
    }
 
    public void method() {
        System.out.print("父类的method()\t");
    }
    public void method2() {
        System.out.print("父类的method2()\t");
    }
 
}
 
class SonClass extends Father {
 
    public SonClass() {
        System.out.print("子类的构造方法\t");
    }
 
    @Override
    public void method() {
        System.out.print("子类的method()\t");
    }
 
}

5. 使用接口改写例6.8中的程序。

//Shapes接口
package runshape;

public interface Shapes {
    public double getArea();
    public double getPerimeter();
    public void show();
}
package runshape;

public class Circle implements Shapes{
    private int r;
    public Circle(int r){
        this.r=r;
    }

    public double getArea() {
        return Math.PI*Math.pow(r, 2);
    }
    public double getPerimeter(){
        return 2*Math.PI*r;
    }

    public void show(){
        System.out.println("圆形:");
        System.out.println("圆的面积是"+this.getArea());
        System.out.println("圆的周长是"+this.getPerimeter());
    }
}
package runshape;

public class Rect implements Shapes{
    private int height;
    private int width;
    public Rect(int height, int width){
        this.height=height;
        this.width=width;
    }
    public double getArea(){
        return height*width;
    }
    public double getPerimeter(){
        return 2 * height + 2 * width;
    }
    public void show(){
        System.out.println("矩形:");
        System.out.println("矩形的面积是"+this.getArea());
        System.out.println("矩形的周长是"+this.getPerimeter());
    }

}
package runshape;

public class Triangle implements Shapes {
    private int x;
    private int y;
    private int z;
    public Triangle(int x, int y, int z){
        this.x=x;
        this.y=y;
        this.z=z;
    }

    @Override
    public double getArea() {
        double m=(x+y+z)/2.0;
        return Math.sqrt(m*(m-x)*(m-y)*(m-z));
    }

    @Override
    public double getPerimeter() {
        return x+y+z;
    }

    public void show(){
        System.out.println("三角形:");
        System.out.println("三角形的面积是"+this.getArea());
        System.out.println("三角形的周长是"+this.getPerimeter());
    }

}
package runshape;

public class RunShape {
    public static void print(Shapes s){
        s.show();
    }
    public static void main(String[] args) {
        Rect rect=new Rect(25,25);
        Triangle triangle=new Triangle(5,5,8);
        Circle circle=new Circle(12);

        //打印输出
        print(rect);

        print(triangle);

        print(circle);
    }


}

6. 简述运算符instanceof的使用场景。

  • 用法:判断对象是否为特定类的实例,还可以将这个对象强制转换成这个类的类型
class Uncle{}
class Pare{}
class Pare1 extends Pare{}
class Pare2 extends Pare1{}
class Pare3 {
   	  public static void main(String[] args){
   		Uncle  u  = new Uncle();
		Pare   p  = new Pare();
	 	Pare1  p1 = new Pare1();
	 	Pare2  p2 = new Pare2();
	 	if ( p instanceof Pare)
	 		{System.out.println("p instanceof Pare");}
	 	if (!( p1 instanceof Pare))
	  		 {System.out.println("p1 not instanceof Pare");}
		 else
	   		{System.out.println("p1  instanceof Pare");}
	 	if ( p2 instanceof Pare)
	   		{System.out.println("p2 instanceof Pare");}
	 	if ( p1 instanceof Pare1)
	   		{System.out.println("p1 instanceof Pare1");}
	 	if ( p2 instanceof Pare1)
	   		{System.out.println("p2 instanceof Pare1");}
	 	if ( p1 instanceof Pare2)
	   		{System.out.println("p1 instanceof Pare2");}
		 else
	   		{System.out.println("p1 not instanceof Pare2");}
	 	/*if (p instanceof Uncle)
	 		{System.out.println("p instanceof Uncle");}
	 	else
	 		{System.out.println("p not instanceof Uncle");}*/
	 	if (null instanceof String)
	  		 {System.out.println("null instanceof String");}
	 	else
	   		{System.out.println("null not instanceof String");}
   	  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值