第三 章、面向对象 第一步部分

一、类与对象的基本概念

类:抽象的概念集合,表示的是一个共性的产物,类之中定义的是属性和行为(方法);

对象:是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性区分不同的对象。

类与对象的区别:类是对象的模板,对象是类的实例,类只有通过对象才可以使用,开发中应该先产生类,再产生对象。类不能直接使用,方法可以直接使用。

二、类与对象的定义

1、类的定义:

在JAVA中定义类,可以使用class关键字完成, 语法为:

1 class 类名称{
2     属性(变量);
3     行为(方法);
4 }

范例:定义一个Person类。

1 class Person {
2     String name;
3     int age;
4
5     public void tell() {
6         System.out.println("姓名:" + name + ",年龄:" + age);
7     }
8 }

2、对象的定义:

定义完类之后,无法直接使用,要使用,必须依靠对象使用,由于类属于引用数据,对象的定义格式如下:

格式一:声明并实例化对象

类名称   对象名称   =  new  类名称  ()

格式二:分布完成

声明对象:     类名称   对象名称 = null;

实例化对象:  对象名称 =  new  类名称();

以后只要是引用数据类型的实例化操作,永远都会存在关键字new(分配空间)。当一个实例化的对象产生后,可以按照如下方式进行类的操作:

  • 方法.属性:表示调用类之中的属性
  • 方法.对象():表示调用类之中的方法

范例1:使用对象操作类

 1 class Person1 {
 2     String name;
 3     int age;
 4
 5     public void tell() {
 6         System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8 }
 9
10 public class TestPerson {
11     public static void main(String[] args) {
12         Person1 per = new Person1();
13         per.name = "张三";
14         per.age = -30;
15         per.tell();
16     }
17 }

姓名:张三,年龄:-30

格式二分步完成操作类,范例2

 1 class Person1 {
 2     String name;
 3     int age;
 4
 5     public void tell() {
 6         System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8 }
 9
10 public class TestPerson {
11     public static void main(String[] args) {
12         Person1 per = null;
13         per = new Person1();
14         per.name = "张三";
15         per.age = -30;
16         per.tell();
17     }
18 }

姓名:张三,年龄:-30

格式一与格式二运行结果一致,两者的区别引入内存解释:

堆内存:保存真正的数据

栈内存:保存一块堆内存的空间地址

上图为上述程序的内存分析图,过程:声明对象——实例化对象——为对象的name属性赋值——为对象的age属性赋值

范例3、产生两个对象的操作:



 1 class Person1 {
 2     String name;
 3     int age;
 4
 5     public void tell() {
 6         System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8 }
 9
10 public class TestPerson {
11     public static void main(String[] args) {
12         Person1 per2 = new Person1();
13         Person1 per1 = null;
14         per1 = new Person1();
15
16         per1.name = "张三";
17         per2.name = "李四";
18         per1.age = 30;
19         per2.age = 20;
20         per1.tell();
21         per2.tell();
22     }
23 }


姓名:张三,年龄:30
姓名:李四,年龄:20

内存分析图:声明per1,声明并实例化per2——实例化per2——为per1对象属性赋值——为per2对象属性赋值

范例4、异常代码:

 1 class Person1 {
 2     String name;
 3     int age;
 4
 5     public void tell() {
 6         System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8 }
 9
10 public class TestPerson {
11     public static void main(String[] args) {
12         Person1 per1 = null;//只声明,未实例化per1,只有栈内存,没有堆内存
13         per1.name = "张三";
14         per1.age = 30;
15         per1.tell();
16
17     }
18 }

运行结果:Exception in thread "main" java.lang.NullPointerException(空间指向异常)
              at hello.TestPerson.main(TestPerson.java:15)
这种异常只会在在用数据类型产生,并很常见,解决方案:查找引用数据类型,观察其是否被实例化

引用传递:同一块堆内存空间同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。

范例4:

 1 class Person1 {
 2     String name;
 3     int age;
 4
 5     public void tell() {
 6  

   System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8 }
 9
10 public class TestPerson {
11     public static void main(String[] args) {
12         Person1 per1 = new Person1();
13         per1.name = "张三";
14         per1.age = 20;
15         Person1 per2 = per1;
16         per2.name = "李四";
17         per1.tell();
18
19     }
20 }

姓名:李四,年龄:20

范例5:

 1 class Person1 {
 2     String name;
 3     int age;
 4
 5     public void tell() {
 6         System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8 }
 9
10 public class TestPerson {
11     public static void main(String[] args) {
12         Person1 per1 = new Person1();
13         Person1 per2 = new Person1();
14         per1.name = "张三";
15         per1.age = 20;
16         per2.name = "李四";
17         per2.age = 30;
18         per2 = per1;
19         per2.name = "王五";
20         per1.tell();
21
22     }
23 }

结果:姓名:王五,年龄:20

垃圾:在开发程序中,没有任何对象所指向的一块堆内存空间,这块内存空间被称为垃圾,所有垃圾等待GC(垃圾收集器)不定期的进行回收与空间的释放。

3、封装性

范例1:

1 public class Person1 {
2     String name;
3     int age;
4
5     public void tell() {
6         System.out.println("姓名:" + name + ",年龄:" + age);
7     }
8 }
1 public class TestDemo2{
2     public static void main(String[] args) {
3         Person1 p = new Person1();
4         p.name="王娜";
5         p.age=-30;
6         p.tell();
7     }
8 }

运行结果:姓名:王娜,年龄:-30

虽然年龄不可能为负数,但是依然可以执行,这属于业务逻辑错误,出错的关键是没有检查要设置的内容,检查的第一步是让用户看不见操作的东西,此时,用private关键字,将类中的属性进行私有化操作。

范例2:使用private封装类中属性

 1 class Person4 {
 2     private String name;
 3     private int age;
 4
 5     public void tell() {
 6         System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8
 9 }
10
11 public class Person3 {
12     public static void main(String[] args) {
13         Person4 per = new Person4();
14         per.name = "张三";//语法错误,无法访问私有属性
15         per.age = -30;//语法错误,无法访问私有属性
16         per.tell();//对象.方法
17     }
18 }

Exception in thread "main" java.lang.Error: Unresolved compilation problems:
    The field Person4.name is not visible
    The field Person4.age is not visible
    at hello.Person3.main(Person3.java:16)    属性被封装,但是无法被外部操作,为此,如果访问类中的私有属性,按如下形式定义操作方法:
setter(以"private String name"属性为例):public void setName(String n);

getter(以"private String name"属性为例):public void getName().

范例3:编写setter()和getter()方法

 1 public class Person {
 2     private String name;
 3     private int age;
 4
 5     public void setName(String n) {
 6         name = n;
 7     }
 8
 9     public void setAge(int a) {
10         age = a;
11     }
12
13     public String getName() {
14         return name;
15     }
16
17     public int getAge() {
18         return age;
19     }
20
21     public void tell() {
22         System.out.println("姓名:" + name + ",年龄:" + age);
23     }
24 }
1 public class Person1 {
2     public static void main(String[] args) {
3         Person per=new Person();
4         per.setName("张三");
5         per.setAge(20);
6         per.tell();
7     }
8 }

姓名:张三,年龄:20

虽然以上代码可以访问,但是没有加入验证。在开发时,加入验证是在setter中加入,getter只是简单的将数据返回。

范例4:加入验证

 1 public class Person {
 2     private String name;
 3     private int age;
 4
 5     public void tell() {
 6         System.out.println("姓名:" + name + ",年龄:" + age);
 7     }
 8 public void setName(String n){
 9     name=n;
10 }
11 public void setAge(int a){
12     if(a>=0&&a<=0){
13     age=a;
14 }
15 }
16 public String setName(){
17     return name;
18 }
19 public int setAge(){
20     return age;
21 }
22     }
1 public class Person1 {
2     public static void main(String[] args) {
3         Person per=new Person();
4         per.setName("张三");
5         per.setAge(-20);
6         per.tell();
7     }
8 }

姓名:张三,年龄:0

年龄是-20,不符合逻辑,故置0.

以后在定义类的时候,所有属性都要编写private封装,封装后的属性如果需要被外部操作,则编写setter()和getter()。

4、构造方法(构造方法是在实例化对象的时候使用,而普通方法是在实例化对象产生之后使用的)

定义:构造方法的名称和类名称保持一致;

构造方法不允许有返回值声明;

由于对象实例化操作一定需要构造方法的存在,所以,如果在类中没有明确定义构造方法的话,则会自动生成一个无参,无返回值的构造方法,如果一个类之中已经明确定义了一个构造方法的话,则无实际意义的构造方法就不会自动生成,即一个类之中至少存在一个构造方法。

范例4.1:默认情况下会存在一个无参无返回值的构造方法。

1 class Person(){//类名称首字母大写
2     public Person(){//无参无返回值的方法
3     }
4 }

作用:在对象实例化的时候,通过构造方法为类中的属性初始化。

范例4.2:在类中定义有参构造方法。

 1 public class Person {                                      //类名称首字母大写
 2     private String name;                                   //属性封装
 3     private int age;                                       //属性封装
 4
 5     public Person(String n, int a) {                       //通过构造方法赋值
 6         setName(n);                                        //设置name属性内容
 7         setAge(a);                                         //设置age属性内容
 8     }
 9
10     public void tell() {
11         System.out.println("姓名:" + name + ",年龄:" + age);
12     }
13
14     public void setName(String n) {                         //setter:设置name属性内容
15         name = n;
16     }
17
18     public void setAge(int a) {                              //setter:设置age属性内容
19         if (a >= 0 && a <= 250) {                            //增加检查
20             age = a;                                         //满足条件赋值
21         }
22     }
23
24     public String getName() {                                //getter:取得name属性
25         return name;
26     }
27
28     public int getAge() {                                     //getter:取得age属性
29         return age;
30     }
31 }
1 public class TestDem {
2     public static void main(String[] args) {
3         Person per = new Person("张三", 30);// 声明并实例化对象
4         per.tell();// 对象.方法()
5     }
6 }

姓名:张三,年龄:30

另外:可以用”this.()方法“表示调用本类中的方法,以下代码与范例4.2中代码一样

1 public Person(String n, int a) {                       //通过构造方法赋值
2         this.setName(n);                         //设置name属性内容
3         this.setAge(a);                           //设置age属性内容
4     }

范例4.3:构造方法重载

 1 public class Person { // 类名称首字母大写
 2     private String name; // 属性封装
 3     private int age; // 属性封装
 4
 5     public Person() { // 无参构造方法
 6     }
 7
 8     public Person(String name) {
 9         this.setName(name);
10     }
11
12     public Person(String n, int a) {
13         setName(n);
14         setAge(a);
15     }
16
17     public void tell() {
18         System.out.println("姓名:" + name + ",年龄" + age);
19     }
20
21     public void setName(String n) {
22         name = n;
23     }
24
25     public void setAge(int a) {
26         if (a >= 0 && a <= 250) {
27             age = a;
28         }
29     }
30
31     public String getName() {
32         return name;
33     }
34
35     public int getAge() {
36         return age;
37     }
38 }
public class TestDem {
    public static void main(String[] args) {
        Person per = new Person("张三");// 声明并实例化对象
        per.tell();// 对象.方法()
    }
}

姓名:张三,年龄0

在本程序Person类中定义了三个构造方法,在主类中实例化对象时调用了一个参数的构造,结果只为name赋值,年龄为0.

在一个类中对构造方法重载时,所有的重载方法按照参数的个数由多到少或由少到多

5、匿名对象

按内存关系,对象名称可以被解释为在栈内存中保存,而对象的具体内容(属性)在对内存之中保存,所以匿名对象没有对应的栈内存指向,只能使用一次,一次之后将成为垃圾,并且等待GC回收释放。

范例:

 1 public class Person {
 2     private String name;
 3     private int age;
 4
 5     public Person(String n, int a) {
 6         name = n;
 7         age = a;
 8     }
 9
10     public void tell() {
11         System.out.println("姓名:" + name + ",年龄" + age);
12     }
13     // settter、getter省略
14 }
1 public class TestDem {
2     public static void main(String[] args) {
3         new Person("张三", 20).tell();// 匿名对象.方法
4     }
5 }

姓名:张三,年龄20

时间: 2024-10-02 19:04:49

第三 章、面向对象 第一步部分的相关文章

第三章面向对象编程思想

""" 编码规范: 类名首字母应以大写字母开头 类的成员/属性: 成员属性 实例化对象的属性: self.name=name 可以被访问,也可以在类的外部被修改 私有属性 实例化对象的私有属性: self.__age=age 属性名前加两下划线 外部无法被访问, 也不能被修改,只能内部访问和修改 想要在外部访问只能自定义一个方法了 强制访问 私有属性: p._People__age 对象名._类名__私有属性 公共属性: 类的属性,也叫静态属性,他是在类的内部定义的 clas

Learn Prolog Now 翻译 - 第三章 - 递归 - 第一节,递归的定义

在Prolog中,谓词可以递归地定义.简要地讲,一个谓词是递归定义的,如果一个或者多个规则的定义中包含了规则自身. 例子1:消化 考虑如下的知识库: is_digesting(X, Y) :- just_ate(X, Y). is_digesting(X, Y) :- just_ate(X, Z), is_digesting(Z, Y). just_ate(mosquito, blood(john)). just_ate(frog, mosquito). just_ate(stork, frog

第三章 面向对象编程 3.1类型系统

3.1.2 值语义与引用语义 值语义和引用语义的定义就是 复制后与之前的对象无关的对象叫做值语义 无法复制或者复制以后与原来对象存在关联的对象称为引用语义 C语言的数组在做函数参数传递的时候就是作为引用语义 但是作为结构体里面定义的时候就是值传递 但是go语言的里面数组都是值传递 go也存在四种引用语义的类型 1.切片数组 你可以把[]T看作为,其实就是一个指向数组的指针 type slice struct{ first *T len int cap int } 2.map map本质上是一个字

Java基础复习---第三章

第三章 面向对象 面向对象更加强调运用人类在日常的是为逻辑中采用的思想方法与原则 抽象.分类.继承.聚合.多态 面向对象与面向过程 ? 面向过程:强调的是功能行为 ? 面向过程:将功能封装进对象,强调具备了功能的对象 面向对象三大特征 ? 封装.继承.多态 OOP思想概述 类 :对现实世界事物的抽象定义 对象:类的实体(实例) ? ? ps. 类就像汽车设计图 对象就像实际的汽车 ? 类(class)和对象(object)是面向对象的核心概念.类是对现实世界事物的描述,类是抽象.概念上的定义.

进击的Python【第六章】:Python的高级应用(三)面向对象编程

Python的高级应用(三)面向对象编程 本章学习要点: 面向对象编程介绍 面向对象与面向过程编程的区别 为什么要用面向对象编程思想 面向对象的相关概念 一.面向对象编程介绍 面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法.对象指的是类的实例. 已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用. 此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它

杨森翔:春节文化大观上编 第三章 春节古诗词 目录 第一节:春节诗词概述 一、 除夕诗词概述 二、元日诗词概述 三、 元宵诗词概述 第二节:春节古诗词拾萃

杨森翔:春节文化大观上编 第三章 春节古诗词 目录 第一节:春节诗词概述 一. 除夕诗词概述 二.元日诗词概述 三. 元宵诗词概述 第二节:春节古诗词拾萃 一.腊祭诗词 二.祭灶诗词 三.除夕诗词 四.元旦诗词 五.人日诗词 六.元宵诗词 第一节:春节古诗词概述 中国的春节,作为除旧迎新的节日,时间相当长,从年前的腊月二十三,天空中就似乎弥漫了节日的气息.这种节日的气氛,在保持传统风俗较好的地方,甚至会持续到二月二龙抬头的时候,但欢度春节的高潮,应该说是自除夕始一直到上元之夜.因此,历代歌咏和反

【算法竞赛入门经典】【第三章】课后习题(第一部分)

课后习题第三波来了,到第三章之后代码之类的稍微变长了一些,所以我把这一章的答案分为几部分.这一章重点是字符串的处理,对于字符串问题,通常只要细心就没有问题了,下面不多说了直接上详解. 习题3-1 分数统计(stat) 任务1:这个比较简单就直接上代码了: #include <stdlib.h> #include <stdio.h> #include <string.h> #define MAXN 100 + 10 int cmp(const void*a,const v

笔记--《谷歌和亚马逊是怎么做产品的》第一至三章

前言:既然是笔记,我只mark了我觉得对我现阶段有用的东西.并非书中全部内容总结. 第一章,产品需求挖掘 ................略,基本大同小异 第二章,产品定义 第一步,写新闻稿: name 预计发布时间 target customer 解决了什么问题: how to solve(核心功能点). 第二步,创建并且不断更新的FAQ文档: SVN ★★★★★ Dropbox ★★★★ Windows Live Sync ★★★★★ 这几个就是网上推荐的工具?好多人推荐用wiki的喔,但是

《构建之法》第一、二、三章读后感

第一章系统地告诉了我们什么是软件,也就是软件=程序+软件工程,软件工程是怎样的一个存在,包括软件的种类和性质,都系统地分析给我们,更是强调了一个工程团队对软件工程的重要性,同时也给我们指出了某些软件会出现的问题,比如说会有BUG,给我们介绍了当遇到这些问题的时候需要怎样去解决问题和修正BUG,完成客户给我们的要求.总的来说,第一章就是带我们走进了软件工程的线索. 第二章叫做个人技术和流程,在这一章中我看到了程序执行过程中耗时最多的三个函数,三个函数加起来占用了整个程序的84%的时间,并给我们分析