栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA第六章(面向对象下)小结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA第六章(面向对象下)小结

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

//例6.4:显式使用super调用父类的构造方法
class AddClass {
    private 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;
    }
}
public class SonAddClass extends AddClass{
    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;
    }//super(x,y,z)如果去掉会如何?
    public int add() {
        System.out.println("super: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="+p2.add());
        System.out.println("a="+p3.add());
    }
}

//例6.5:隐式使用super调用父类的构造方法
class Pare {
    int i=3;
    Pare(){
        System.out.println("call super()");
    }
}
class Construct extends Pare {
    int i = 10;
    Construct() {
        System.out.println("execute Construct()");
    }
    Construct(int num) {
        this(); //如果去掉此句呢?
        System.out.println("execute Construct(int)");
    }
    public static void main(String[] args) {
        Construct ct = new Construct(9);
        System.out.println(ct.i);
    }
}

 

总结:子类对象实例化过程

(1)为子类对象分配内存空间,对成员变量进行默认的初始化

(2)绑定子类构造方法,将new中的参数传递给构造方法的形式参数。

(3)显式或隐式调用super语句,对从父类继承来的实例变量进行初始化。

(4)按定义顺序执行实例变量初始化操作。  

(5)执行子类构造方法的剩余代码。 

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

class Src
{
    int s;
    public Src(int _s){//构造函数,保证s的非负
        if(_s>=0)
            s = _s;
        else s=0;
    }
    public void change(Dis d){//设计一个特殊的方法来改变s的值,每次改变都会给Dis对象发通知
        for(int a=1;a<5;a++)
        {
            d.get();
            s=s+a*2;
        }
    }
}
class Dis
{
    Src src;
    public Dis(Src s){
        this.src = s; //Dis对象中拥有了Src对象的引用
    }
    public void invoke(){
        //Dis中对象发送消息给Src的对象
        System.out.println(src.s);
    }
    public void get()//用来接收通知的方法
    {
        this.invoke();
    }
}
 
public class Helloworld {
    public static void main(String[] args) {
        Src src = new Src(5);
        //产生Dis对象,并将Src对象引用作为参数传入
        Dis  dis   = new Dis(src);
        //发送消息,产生调用关系
        dis.src.change(dis);
    }
}

3. 谈谈组合与继承的区别以及两者的使用场景(即什么时候宜用组合 ?什么时候宜用继承?)。

组合和继承是面向对象中两种代码复用的方式。

组合:在新类里面创建原有类的对象,重复利用已有类的功能。(has-a关系)

继承:可以使用现有类的功能,并且在无需重复编写原有类的情况下对原有类进行功能上的扩展。(is-a关系)

>>除非两个类之间是“is-a”的关系,否则不要轻易的使用继承,不要单纯的为了实现代码的重用而使用继承,因为过多的使用继承会破坏代码的可维护性,当父类被修改时,会影响到所有继承自它的子类,从而增加程序的维护难度和成本。


>>不要仅仅为了实现多态而使用继承,如果类之间没有“is-a”的关系,可以通过实现接口与组合的方式来达到相同的目的。设计模式中的策略模式可以很好的说明这一点,采用接口与组合的方式比采用继承的方式具有更好的可扩展性。


>>在Java语言中,能使用组合就尽量不要使用继承。

参考原文链接:https://blog.csdn.net/weixin_40995778/article/details/83306945

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

多态分为两种情况:编译时多态和运行时多态

方法重载都是编译时多态。根据实际参数的数据类型、个数和次序,Java在编译时能够确定执行重载方法中的哪一个。

运行时多态:程序运行时,Java从实例所属的类开始寻找匹配的方法执行,如果当前类中没有匹配的方法,则沿着继承关系逐层向上,依次在父类或各祖先类中寻找匹配方法,直到Object类。

注意:父类对象只能执行那些在父类中声明、被子类覆盖了的子类方法。

如果要执行子类中父类没有的方法呢?

public class Test {   //例子2
    public static void main(String[] args) {
        Person p = new Man();
        System.out.println(((Man) p).getName());   //返回结果为Man
    }
}
class Person{}

class Man extends Person{
    public String getName(){
        String name = "Man";
        return name;
    }
}

此例中Person类型要引用Man类的实例,因Person中未定义setName()方法,故需要把Person类显式转换为Man类,然后调用Man中的getName方法。

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

abstract class Shape {
    protected double x,y,z; //子类可见
    //抽象方法
    abstract public double getArea();
    abstract public double getPerimeter();
    //抽象类可以有构造方法,初始化从父类继承的实例变量
    public Shape(double x,double y,double z){
        this.x = x;
        this.y = y;
        this.z = z;
    }
}
class Rect extends Shape {
    public Rect(double height, double width) { super(height,width, 0.0); }
    public double getArea(){
        return x * y;
    }
    public double getPerimeter(){
        return (x + y)*2;
    }
}
class Circle extends Shape{
    public Circle(double radius){
        super(radius,0.0,0.0);
    }
    public double getArea(){
        return( x * x *Math.PI);
    }
    public double getPerimeter(){
        return(2*Math.PI* x);
    }
}
class Triangle extends Shape {
    public Triangle(double lenX,double lenY,double lenZ){
        super(lenX, lenY, lenZ);
    }
    public double getArea(){
        double m= (x + y+ z)/2.0;
        return Math.sqrt(m*( m-x)*( m-y)*(m-z));
    }
    public double getPerimeter(){
        return x + y + z;
    }
}
public class TestShape {
    public static void main(String[] args) {
        Rect rect = new Rect(25,25);//长方形
        Triangle tri = new Triangle(5,5,8);//三角形
        Circle cir = new Circle(12.5);//圆
        printArea(rect);
        printPerimeter(rect);
        printArea(tri);
        printPerimeter(tri);
        printArea(cir);
        printPerimeter(cir);
    }
    public static void printArea(Shape s){
        System.out.println(s.getClass().getName() +
                " Area:"+s.getArea());
    }
    public static void printPerimeter(Shape s){
        System.out.println(s.getClass().getName() +
                "Perimeter:"+s.getPerimeter());
    }
}

改写:

interface Shape {
    //抽象方法
    public abstract  double getArea();
    public abstract double getPerimeter();
    //无构造方法
}
class Rect implements Shape {
    private int x,y;
    public Rect(int x,int y) {
        this.x=x;
        this.y=y;
    }
    public double getArea(){
        return x * y;
    }
    public double getPerimeter(){
        return (x + y)*2;
    }
}

class Circle implements Shape{
    private double x;
    public Circle(double v) {
        this.x=v;
    }
    public double getArea(){
        return( x * x *Math.PI);
    }
    public double getPerimeter(){
        return(2*Math.PI* x);
    }
}

class Triangle implements Shape {
    private int x,y,z;
    public Triangle(int x,int y,int z) {
        this.x=x;
        this.y=y;
        this.z=z;
    }
    public double getArea(){
        double m= (x + y+ z)/2.0;
        return Math.sqrt(m*( m-x)*( m-y)*(m-z));
    }
    public double getPerimeter(){
        return x + y + z;
    }
}
public class TestShape {
    public static void main(String[] args) {
        Shape rect = new Rect(25,25);//长方形
        Shape tri = new Triangle(5,5,8);//三角形
        Shape cir = new Circle(12.5);//圆
        printArea(rect);
        printPerimeter(rect);
        printArea(tri);
        printPerimeter(tri);
        printArea(cir);
        printPerimeter(cir);
    }
    public static void printArea(Shape s){
        System.out.println(s.getClass().getName() +
                " Area:"+s.getArea());
    }
    public static void printPerimeter(Shape s){
        System.out.println(s.getClass().getName() +
                "Perimeter:"+s.getPerimeter());
    }
}


 

6. 自定义一个类,覆写equals方法,以满足自身业务需求    

class Pare{}
class Pare1 extends Pare{}
class Pare2 {
    public static void main(String[] args){
        Pare   p  = new Pare();
        Pare1  p1 = new Pare1();
        Pare   pp = p1;
        if (p1.equals(pp)) {
            System.out.println("p1与pp引用相同");}
        else {
            System.out.println("p1与pp引用不同");}
        if (p.equals(pp)) {
            System.out.println("p与pp引用相同");}
        else {
            System.out.println("p与pp引用不同");}
    }
}//p1与pp引用相同 p与pp引用不同

7. 举例说明运算符instanceof的使用场景。

instanceof:二元运算符。

格式:a instanceof A.

应用:其中a为对象的引用,A为类。如果a为A的实例或是其子类关系,则返回true。如果a是A父类的实例,则返回false。如果a对象的类和A没有任何关系,则编译不会通过。

例如:

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 (p1 instanceof Pare2) {
            System.out.println("p1 instanceof Pare2");
        } else {
            System.out.println("p1 not instanceof Pare2");
        }

        
        if (null instanceof String) {
            System.out.println("null instanceof String");
        } else {
            System.out.println("null not instanceof String");
        }
    }
}

 

8. 谈谈抽象类与接口的异同以及两者的使用场景。

共同点:

二者都可具有抽象方法,都不能实例化,但都可以有自己的声明,并能引用子类或实现类对象。

不同点:

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/329107.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号