JAVA--封装,继承

本篇讲述面向对象其中两个重要思想:封装与继承,方法重写以及Object类的两个常用方法.

封装

是将类的某些信息隐藏在类的内部,不允许其他类及程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问,一般是public 修饰的get/set方法.

封装可以有效地提高代码的安全性,可维护性提高.

规则:将需要隐藏的元素用private修饰,本类中提供public修饰的get/set方法提供访问接口.

代码实例:

public class PrivateTest {
/*其他类无法访问到private修饰的变量.*/
    private int num1=15;
    private int num2=35;

    /*提供get/set方法给其他程序访问接口
    * 使用IDE可以自动生成,
    * Eclipse是Alt+Shift+s→Getter/Setter
    * IDEA是Alt+Insert→Getter/Setter.
    * */

    public int getNum1() {
        return num1;
    }

    public void setNum1(int num1) {
        this.num1 = num1;
    }

    public int getNum2() {
        return num2;
    }

    public void setNum2(int num2) {
        this.num2 = num2;
    }
    /*提供get/set方法之后其他类就可以访问这个类的私有变量了*/
}

测试类TestPrivate:

public class TestPrivate{

    public static void main(String[] args) {
        ObjectTest o = new ObjectTest();
       // o.num1;//这样是无法访问其他类的私有变量的
       System.out.println("Getter方法访问的num1:"+o.getNum1());
       System.out.println("Getter方法访问的num2:"+o.getNum2());
       o.setNum1(7);
       o.setNum2(6);
       System.out.println("Setter方法设置的num1:"+o.getNum1());
       System.out.println("Setter方法设置的num2:"+o.getNum2());
    }
}

运行结果:

Getter方法访问的num1:15
Getter方法访问的num2:35
Setter方法设置的num1:7
Setter方法设置的num2:6

 直接调取私有变量会失败,只能通过get方法来调用,可以保证封装的数据的安全.

继承

从已有的类中吸收成员变量和方法,新的类型中可以添加新的方法和成员变量.这种方式可以提高代码复用性,缩短开发周期,减少开发费用.

计算机语言中,先编写父类,再编写子类,然后再有对象.

子类也叫派生类,subCLass .父类也叫超类,基类, superClass

扫描二维码关注公众号,回复: 5037339 查看本文章

 

继承必需的关键字:extends:

用于继承语法.格式: public class subCLass extends superClass{}

所有的类都默认继承自Object类,但是一般不写extens Object.

继承中的构造器:

子类不能继承父类的构造器,但是子类中的构造器可以调用父类的构造器.

语法:super(有参传实参);

子类中的构造器一定会有1个调用了父类的构造器.

父类中如果没有无参构造器,子类需要显式调用父类构造器,如果父类中有无参构造器,子类中的构造器可能隐式调用了父类的无参构造器super().即隐藏了super().

 

super();与this();的区别与相同点

相同点:都是调用构造器,且必须放在首行首句.

区别:super();是调用父类的构造器,this();是调用本类中其他构造器.

继承的传递性

继承特征有传递特性.

如b extends a,  c extends a,表明c间接继承了a.

JAVA只支持单继承,即extends之后只能有一个类,可以继承一个已经是子类的父类,且一个父类可以有多个子类

编译期绑定:编译过程中变量只能调出本类中的方法.

运行期绑定:运行过程中真正执行的方法的逻辑与对象的类型有关

成员变量都与变量的类型有关,与编译期运行期无关

简单地说,方法在运行期间动态绑定到对象上,

方法在编译期间方法静态绑定到变量上.

下面给一个实例来理解继承:

父类SuperClass:

public class SuperClass {
    int x;
    int y;

    public SuperClass(int x,int y){
        this.x=x;
        this.y=y;
    }

    public void sum(int x,int y){
        System.out.println("父类的sum方法:"+(x+y));
    }

    public String toString() {
        return "父类重写的Object类的toString:x"+x+",y:"+y+".";
    }
}

子类SubClass:

public class SubClass extends SuperClass{

    int z;

    public SubClass(int x,int y,int z){
        super(x,y);
        this.z=5;//直接赋值.
    }

    @Override
    public void sum(int x, int y) {
        System.out.println("子类重写的sum方法:"+(x+y));
    }


    public String toString() {
        return "子类重写的toString:x"+x+",y:"+y+",z:"+z+".";
    }

    public static void main(String[] args) {
        SubClass sub=new SubClass(1,2,3);
        SuperClass sup=new SubClass(4,5,6);

        System.out.println(sub);
        System.out.println(sup);

        sub.sum(15,9);
        sup.sum(18,10);
    }
}

运行结果:

子类重写的toString:x1,y:2,z:5.
子类重写的toString:x4,y:5,z:5.
子类重写的sum方法:24
子类重写的sum方法:28

 

方法重写:@Override

子类可以继承父类的方法.在继承时,我们可以在子类中编写与父类方法名,参数列表也相同的方法(如toString方法.).

父子类关系,方法名相同,参数列表(形参类型顺序)相同.

返回值类型可以相同,也可以不同.

不同时,子类方法返回值的类型必须是父类方法的返回值类型的子类

修饰词可以不变,或者比父类的修饰权限(访问范围)更大.

如父类使用了protected,则子类只能使用public和protected.而不能使用默认与private.

父类型的变量可以引用子类型的对象.
 

方法重载(@Overload)的区别

方法重载:同一个类中,方法名相同,参数列表不同.

方法重写:子类重写父类方法,方法名相同,参数列表相同,返回值类型可以相同,也 可以说父类方法返回值类型的子类.修饰词可以相同,或者修饰权限 比父类的大,父类的私有方法不能重写.

Object类

Object类是所有Java类的祖先。每个类都使用 Object 作为父类。所有对象(包括数组)都实现Object类的方法,如常用的toString方法与equals方法。

toString方法:

先看看Object类中的toString方法:

public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

 返回类全名@HashCode值,即对象在内存中的地址信息,在 输出变量或引用变量拼接时默认调用.我们不需要这些信息,所以我们一般都重写toString()方法,用于查看对象的详情.

我们在使用System.out.println()的时候就默认调用了toString方法.

equals方法:

先看看Object类中的equals方法:

public boolean equals(Object obj) {
        return (this == obj);
    }

逻辑是比较调用者this与形参obj的地址信息是否相等,即比较this与obj是不是同一个对象.我们在使用时一般都需要进行重写. 

重写规则:

1.查看传进来的obj是不是null.

if(obj==null) return false;

2.查看传进来的obj是不是this.

if(obj==this) return true;

3.查看传进来的obj是不是本类型.

if(obj.getClass()!=this.getClass())

return false;

可以改为:if(!(obj instanceof 类型))

return false;

instanceof关键字

作用:判断引用变量指向的对象是否属于某一类型.

语法:boolean f=变量名 instanceof 类型名

下面给出一则重写equals方法和toString方法的的实例:

public class ObjectTest {

    int x;
    int y;
    String str;

    public ObjectTest(int x,int y,String str){
        this.x=x;
        this.y=y;
        this.str=str;
    }

    @Override//方法重写的标志,可写可不写
    public boolean equals(Object obj) {
        if (obj==null)//查看是否为空
            return false;
        if (this==obj)//查看是否为同一个对象
            return true;
        if (!(obj instanceof ObjectTest))//看看obj是不是本类型
            return false;
         ObjectTest o=(ObjectTest)obj;//将obj强转为本类型
        if (o.x==this.x&&o.y==this.y&&o.str.equals(this.str))
                //String类型是对象,所以要使用.equals来比对.
            return true;
        return false;
    }

    @Override
    public String toString() {//重写toString
        return "("+x+","+y+","+str+")";
    }

    public static void main(String[] args) {
        ObjectTest o1=new ObjectTest(5,5,"o1");
        ObjectTest o2=new ObjectTest(9,7,"o2");
        ObjectTest o3=new ObjectTest(5,5,"o1");

        System.out.println("测试重写toString之输出o1:"+o1.toString());
        System.out.println("测试重写toString之输出o2:"+o2.toString());
        System.out.println("测试重写toString之输出o3:"+o3.toString());
        System.out.println("测试重写equals方法之比对o2与o1:"+o2.equals(o1));
        System.out.println("测试重写equals方法之比对o3与o1:"+o3.equals(o1));
    }
}

猜你喜欢

转载自blog.csdn.net/bujiujie8/article/details/81412086
今日推荐