zoukankan      html  css  js  c++  java
  • Java基础-学习笔记(六)——类的封装性

    1、类是模板,对象是具体的实例

    2、如果成员函数中的局部变量与成员变量名一致,则该方法对这个变量名的访问是局部变量

    class lesson1
    {
    	int age=9;
    	void talk()
    	{
    		int age = 2;
    		System.out.println("my age is "+age);
    	}
    	public static void main(String [] args)
    	{
    		lesson1 test = new lesson1();//()一定要有,这样它才通过调用系统默认的构造函数
    		test.talk();
    	}
    }
    
    /*
    F:java_example>java lesson1
    my age is 2
    */

    3、生成对象时,内存的分配

    lesson1 test = new lesson1();

    等号左边以类名lesson1作为变量类型定义了一个test变量,来指向等号右边通过new关键字创建的一个lesson1类的实例对象,变量test就是对象的引用句柄,对象的引用句柄是栈中分配的一个变量,对象本身,是在堆中分配的。test的值即为该对象在堆中的首地址。

    4、==与equals的区别

    lesson1 t1 = new lesson1();

    lesson1 t2 = t1;

    leeson1 t3 = new lesson1(); 

    t1,t2两个变量指向同一个对象,即t1、t2中存的都是lesson1的首地址,if(t1==t2),则为true

    t1,t3两个变量分别指向两个新创建的lesson1对象,尽管创建的两个string实例对象看上去一模一样,但它们是两个彼此独立的对象,是两个占据不同存储空间的不同对象,if(t1.equals(t3)),则为true

    t1和t3分别指向了两个新创建的lesson1类对象

    class Person
    {
    	int age;
    	void talk()
    	{
    		System.out.println("my age is "+age);
    	}
    
    public static void main(String [] args)
    {
    	Person p1 = new Person();
    	Person p2 = new Person();
    	p1.age = 5;
    	p1.talk();
    	p2.talk();
    }
    }
    //如果把main()单独拿出来,不放在类中,会报错“需要class, interface或enum”
    /*
    F:java_example>java Person
    my age is 5
    my age is 0
    */
    

      

    5、匿名对象

    class lesson1
    {
    	int age=9;
    	void talk()
    	{
    		int age = 2;
    		System.out.println("my age is "+age);
    	}
    	public static void main(String [] args)
    	{
    		//lesson1 test = new lesson1();//()一定要有,这样它才通过调用系统默认的构造函数
    		new lesson1().talk();
    	}
    }
    
    /*
    F:java_example>java lesson1
    my age is 2
    */
    

      这段代码没有产生任何句柄,而是直接用new关键字创建了一个lesson1的对象,并直接调用它的talk方法,得到的结果和之前是一样的,这个方法执行完,这个对象也就变成了垃圾

    使用匿名对象的两种情况:

    (1)当一个对象只需要进行一次方法调用时,可以使用匿名对象

    (2)将匿名对象作为实参传递给一个函数调用,比如

    public static void getsomeone(Person p)

    {

      ......

    }

    可以使用如下语句来调用这个函数

    getsomeone(new Person.())

    6、实现类的封装性

    在第四点的示例代码中,反映了一个问题,age是Person的一个成员,是它的属性,如果外部的程序能把Person类的属性给修改了,会造成不可预估的错误,就像一个人的年龄,不会因为外部而随意修改。为了限制对象对它属性的修改,我们需要添加private修饰符,来加以限制。但是又要对象能够访问他的属性,那我们就写一个public方法,将它的成员变量的值传递出去。如下图代码所示,我们增加了setAge(),getAge()来实现外部程序对age的赋值和获取,并且还可以统一的对age进行限制。这样我们就实现了对类的封装。

    class Person
    {
    	private int age = 23;
    	public void setAge(int i)
    	{
    		if(i<0)
    			return;
    		age=i;
    	}
    	public int getAge()
    	{
    		return age;
    	}
    	public void talk()
    	{
    		System.out.println("my age is "+age);
    	}
    }
    
    class TestPerson
    {
    	public static void main(String [] args)
    	{
    		Person p1 = new Person();
    		Person p2 = new Person();
    		p1.setAge(-19);
    		p2.getAge();
    		p1.talk();
    		p2.talk();
    	}
    }
    /*
    F:java_example>java TestPerson
    my age is 23
    my age is 23*/
    

      实现封装的目的:

    a 隐藏类的实现细节;

    b 让使用者只能通过事先制定好的方法来访问数据,可以方便的加入控制逻辑,限制对属性不合理的操作;

    c 便于修改,增强代码的可维护性;(比如,我们要更改成员变量的名字,如果不进行封装,那就要每个使用到它的地方都要进行修改,而封装后,只需要改类中这块地方就好)

    d 可进行数据检查。

    一个类通常就是一个小的模块,我们应该让模块尽可能只公开需要让外界知道的内容,其他内容尽量隐藏。在设计模块时,需要追求强内聚、弱耦合。

    7、构造函数

    构造函数的功能主要用于在类的对象创建时定义初始化的状态。

    a 构造函数的特征:

    b 没有返回值;

    c 函数名与类名一致;

    不能在方法中用return返回一个值。

    构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的。

    当一个类只定义了私有的构造函数,将无法通过new关键字来创建其对象.

    当程序中没有显式写出构造函数,会有一个默认的构造函数,并且是无参数的;一旦编程者为类定义了构造函数,那么系统就不再提供默认的构造函数

     1 class Person
     2 {
     3     private int age;
     4     private String name = "unknown";
     5     public void setAge(int i)
     6     {
     7         if(i<0)
     8             return;
     9         age=i;
    10     }
    11     public int getAge()
    12     {
    13         return age;
    14     }
    15     public Person()
    16     {
    17         System.out.println("You are calling me!");
    18     }
    19     public Person(int a)//构造函数的重载
    20     {
    21         age=a;
    22     }
    23     public Person(String n,int a)//构造函数的重载
    24     {
    25         name=n;
    26         age=a;
    27     }
    28     public void talk()
    29     {
    30         System.out.println(name+"  is "+age);
    31     }
    32 }
    33 
    34 class TestPerson
    35 {
    36     public static void main(String [] args)
    37     {
    38         Person p1 = new Person();
    39         Person p2 = new Person(26);
    40         Person p3 = new Person("Jane",20);
    41         p1.talk();
    42         p2.talk();
    43         p3.talk();
    44     }
    45 }
    46 /*如果将public Person()注释掉,则会报错
    47 F:java_example>javac lesson2.java
    48 lesson2.java:38: 错误: 对于Person(没有参数), 找不到合适的构造器
    49                 Person p1 = new Person();
    50                             ^
    51     构造器 Person.Person(int)不适用
    52       (实际参数列表和形式参数列表长度不同)
    53     构造器 Person.Person(String,int)不适用
    54       (实际参数列表和形式参数列表长度不同)
    55 不注释掉的话则打印如下内容
    56 You are calling me!
    57 unknown  is 0
    58 unknown  is 26
    59 Jane  is 20*/
    View Code
  • 相关阅读:
    SQL审核平台
    Redis单线程为什么快简单理解
    性能测试关注指标
    nmon
    pycharm安装教程
    MAVEN中央仓库地址大全
    MAVEN概念、安装与配置、配置文件
    linux在线模拟地址
    HTTP学习链接、书籍
    Java启动exe
  • 原文地址:https://www.cnblogs.com/tiantianxiangshang33/p/4934713.html
Copyright © 2011-2022 走看看