首页 > 技术文章 > 类和封装

yellowchives 2021-08-27 17:47 原文

类和对象的关系:

  • 类:类是对现实生活中一类具有共同属性和行为的事物的抽象
  • 对象:是能够看得到摸的着的真实存在的实体
  • 简单理解:类是汽车、对象是丰田卡罗拉、车轮是卡罗拉的成员

类实际上是对象操作的模板,类是不能直接使用的,必须通过实例化对象来使用。

类的定义:

类是由属性和行为两部分组成

  • 属性:在类中通过成员变量来体现(类中方法外的变量,方法内的变量是局部变量)
  • 行为:在类中通过成员方法来体现
package testClass;

//面向对象设计的一大特点就是封装
//规范的程序会把类中的属性隐藏,但是留出访问方式。
public class PrivatePerson{
    private String name;//private关键字确保属性只能在类中访问
    private int age;
    public PrivatePerson(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //为了在外部程序访问和修改属性,提供setter和getter
    //alt+insert可以自动生成setter和getter
    public void setName(String name){
        this.name = name;
    }
    public void setage(int age){
        this.age = age;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }

    //对象的比较非常重要,String类有equals方法来比较不同对象是否相同
    //编写一个对象比较函数
    public boolean compare(PrivatePerson person){
        if(person == null)return false;//防止NullPointerException
        if(this == person)return true;//如果引用对象和本对象地址相同,不用进行具体的判断了

        if(this.name.equals(person.name)&&this.age == person.age) return true;//如果各项属性都相同,返回true
        /*如果类的属性采用了private封装,那么在类的外部不能通过对象直接调用该属性。
        但是如果将一个对象传递回类的方法里,相当于取消了封装,可以直接通过对象访问属性
        所以上面不用写成this.name.equals(person.getName())&&this.age == person.getAge;*/

        else return false;
    }
}

内存情况:同一个类的多个对象在堆内存中有不同的内存划分,成员变量存储在各自的内存区域中,但是成员方法是多个对象共用的。

成员变量和局部变量的区别

  • 类中位置不同:成员变量(类中方法外)局部变量(方法内部或方法声明上)
  • 内存中位置不同:成员变量(堆内存)局部变量(栈内存,随着方法被加载到栈中,当方法调用完毕后自动弹栈消失)
  • 生命周期不同:成员变量(随着对象的存在而存在,随着对象的消失而消失)局部变量(随着方法的调用而存在,醉着方法的调用完毕而消失)
  • 初始化值不同:成员变量(有默认初始化值)局部变量(没有默认初始化值,必须先定义,赋值才能使用)

封装

权限修饰符

通常把属性封装,但是留出方法来调用和修改属性。有以下几种权限修饰符:

image

可以简单的理解为:private只能在一个类中访问,default只能在一个包中访问,protected在不同包的子类中访问,public在所有情况下都可以访问。

public class与class定义类的区别

public class:类名必须与文件名相同。在一个*.java文件中只能有一个public class声明。如果一个类想在不同的包中被使用,就必须定义为public class。

class:文件名可以与类名不同,而且一个*.java文件中可以有多个class声明,编译后会形成多个*.class文件。如果一个类使用class声明,那么这个类只能被本包访问。

在实际的开发中,通常只会使用public class声明,而且一个文件一般只有一个类。

构造器

package testClass;

public class Person {
    String name;
    int age;

    //构造器用来生成实例,可以设置一些默认值.
    //如果不写出来,编译器也会自动生成一个无参构造器
    //构造器和类同名,不能有返回值,前面加一个public
    //使用new关键字其实是在调用构造器,并在堆中开辟空间
    public Person(){
        this.name = "Tom";
    }
    //有参构造,调用时可以传入参数
    //如果写了有参构造,就必须手动写出无参构造
    public Person(String name){
        this.name = name;
    }
    //可以有多个构造器
    //类里的方法可以互相调用
    public Person(String name, int age) {
        this(name);//调用其他构造器。当构造器的代码很多时,常用此方法
        this.age = age;
    }
    public void talk(){
        System.out.println("我是"+this.name);
    }
}

如果一个类只提供了一些方便的函数,不希望用户创建此类的对象,可以提供一个private修饰的无参构造,这样就不能使用构造函数了。

private Math(){}//有了private修饰的无参构造就不能创建对了,因为Math类只提供了一些方便的函数,不需要创建

推荐阅读