java语法基础(三)

类和对象

  面向对象语言概述

  java是一种面向对象的语言,什么是面向对象的语言? 要搞清楚什么是面向对象语言,我们需要相对的了解一下面向过程的语言。 java入门阶段,我们又给大家说过一些语言的分类,比如机器语言,汇编语言,我们称之为低级语言,c语言,java,c++等都属于是高级语言。在高级语言中,c语言属于面向过程语言,java,c++等都属于是面向对象的语言。 面向过程语言特点:所有语句都是谓宾短语,因为cpu是接收和处理命令的唯一单元。存储数据和操作数据都是由cpu完成的。单打独斗,按部就班。是我们数学逻辑的映射。 面向对象语言的特点:对象是接收和处理数据的单元,对象之间各司其职,协同操作,模块化程度更高。分工明确,协同合作。是我们生活逻辑的映射。 相对而言,面向对象语言,易维护,质量高,效率高,易扩展;但是面向过程语言的执行效率较高。 怎么理解他们的特点:举个我们生活中做饭的例子。 面向对象语言的三大基本特征:封装,继承,多态。 在学习面向对象语言过程中,我们要搞清楚两个概念 类 和 对象 类:对具有相同属性或者行为的一类事物的定义(或者叫做抽象)。是看不见,摸不着的一种概念化的东西。 对象:类的实例化,具体化。是客观存在的,符合类所描述特征的具体事物。 怎么去理解这两个概念,比如“人”,人就是一个类,它表示对人这种事物的抽象。提起人这个概念,大家会想起来,两条胳膊两条腿,两只眼睛一张嘴,会说话,会吃饭,是一种社会话程度很高的动物。这个概念停留在脑海中。 那么“小明”就是一个对象,小明是实实在在存在的一个实物,不再是一个概念化的东西,而是看得见摸得着,不再停留在脑海中的一个概念

  面向过程 面向对象 烧菜做饭面向过程的流程: (家里只有你一个单身狗,所以) 去菜市场买菜 回家 洗菜,淘菜 炒菜 端上饭桌 吃饭 面向对象的流程: (你决定请家政保姆的回家做饭服务) 自己打电话给家政公司,申请回家做饭服务 家政公司通知保姆“翠花”接收这次服务 翠花去菜市场买菜 翠花把菜带回家 翠花洗菜,淘菜 翠花曹菜 翠花把菜端上饭桌 自己吃饭

  理解类和对象: 1)从生活逻辑上: 人就是类。 “小明”就是对象。 2)从封装的角度理解: c语言中,结构体:是对数据结构的封装; c语言中,函数:是对处理数据的方法的封装。 类:是对数据结构和处理数据的方法,同时进行封装。 3)编程的角度理解: 类:是一种自定义的类型; 对象:是由这种类型,产生的变量。 4)官方定义 类:具有相同特征的对象的抽象。 对象:某个类的具象。

  类的定义和使用

  java中如果想要创建使用对象,必须先声明类,类就是一个蓝图,有了蓝图,jvm才知道怎么去创建对象。 java中类主要有两个来源: 1 sun公司已经定义好了很多类,存放着jar包中,我们只需要引入使用即可 2 开发者自己通过class关键字定义类,自定义类。 java中类的声明格式: class 类名{ 成员变量;(定义事物的属性) 成员函数;(也叫方法,定义事物的行为) } class:关键字,表示这里要定义一个类 类名:java标识符,符合大驼峰命名法 {}:类的作用范围 成员函数:其实就是一个定义在类的内部,成员方法的外部的变量。符合变量的声明规范。 成员函数:符合函数的声明规范。 声明一个类以后,需要创建对象,才可以调用对象的成员变量和方法(静态类和静态方法我们后面再讲) 我们使用new关键字创建对象。 对象的创建格式: new 类名();为了使用对象,我们需要定义一个变量接收对象: 类名 对象名称 = new 类名(); 对象成员变量的访问 通过.语法来访问对象的成员变量 格式: 对象名称.成员变量 (获取成员变量的值) 对象名称.成员变量=值 (成员变量赋值) 成员函数的调用 通过.语法调用成员函数 格式: 对象名称.成员函数(); 怎么自己定义一个类: 1 确定自己描述的事物,抽离共有的属性和行为 2 根据类的规范,定义类的名称 3 根据累的属性,选择合适类型定义成员变量 4 根据类的行为,定义具有合适返回值类型和参数的成员函数

  比如我们声明一个猫类,用来描述猫 class Cat { String name; int age; public void mew(){ System.out.println("喵~"); } }

  对象的内存图

  

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

  成员变量与局部变量的区别: 定义的位置上 成员变量是定义在方法之外,类之内的。 局部变量是定义在方法之内。 作用上 成员变量的作用是用于描述一类事物的公共 属性的。 局部变量的作用就是提供一个变量给方法内部使用而已。 生命周期 随着对象 的创建而存在,随着对象的消失而消失。 局部变量在调用了对应的方法时执行到了创建该变量的语句时存在,局部变量一旦出了自己的作用域 那么马上从内存中消失。 初始值的 成员变量是有默认的初始值。 数据类型 默认的初始值 int 0 float 0.0f double 0.0 boolean false char ' ' String(引用数据类型) null 局部变量是没有默认的初始值的,必须要先初始化才能使用。

  匿名对象

  匿名对象:没有引用类型变量指向的对象称作为匿名对象。 匿名对象要注意的事项: 1. 我们一般不会给匿名对象赋予属性值,因为永远无法获取到。 2. 两个匿名对象永远都不可能是同一个对象。 匿名对象好处:简化书写。 匿名对象的应用场景: 1. 如果一个对象需要调用一个方法一次的时候,而调用完这个方法之后,该对象就不再使用了,这时候可以使用 匿名对象。 2. 可以作为实参调用一个函数。

   //学生类 class Student{ int num; //学号 String name; //名字 public void study(){ System.out.println("好好学习,为将来称为高帅富做准备!"); } } class Demo4{ public static void main(String[] args) { //创建一个学生对象 //Student s = new Student(); //new Student().name = "狗娃"; //匿名对象 //System.out.println(Student().name); //null System.out.println(new Student() == new Student()) ; // "==" 用于引用类型变量时,比较的是内存地址。判断两个 对象是否为同一个对象 需求: 调用Student的study方法。 Student s = new Student(); s.study(); new Student().study(); } }

  封装

  封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。 权限修饰符:权限修饰符就是控制变量可见范围的。 public : 公共的。 public修饰的成员变量或者方法任何人都可以直接访问。 private : 私有的, private修饰的成员变量或者方法只能在本类中进行直接访问。 protect default 封装的步骤: 1. 使用private修饰需要被封装的属性。 2. 提供一个公共的方法设置或者获取该私有的成员属性。 公共方法命名规范: 设置值的方法: set属性名(); 获取值的方法: get属性名(); 举例:会员的sex属性。

 

构造函数

  构造函数的作用

  使用构造函数可以给对象进行初始化操作。 在没有使用构造函数的时候,我们给每一个成员变量进行赋值,需要通过.语法访问每一个成员变量依次赋值。使用构造函数我们可以在创建对象(new 对象)的时候直接给成员变量进行初始化操作。 我们给对象初始化,可以在声明成员变量的时候直接进行赋值,但是这样的话创建的每个对象的成员变量值就一样了。所以这种方式不能替代构造函数。

  比如创建一个猫 class Cat{ String color; String name; Cat(String c,String n){ color = c; name = n; } } void main(){ //如果没有构造函数 Cat tom = new Cat();//如果定义了带参数的构造函数这里会报错,因为编译器不再自动生产无参数的构造函数 tom.name = "汤姆"; tom.color = "蓝色"; //如果有了构造函数,我们就可以 Cat tom = new Cat(“汤姆”,“蓝色”); }

  构造函数的代码书写格式

  构造函数的代码书写格式: 修饰符 函数名(形式参数){ 函数体... } 构造函数需要注意的细节: 1 构造函数不需要指定返回值类型 2 构造函数函数名必须和类名保持一致 3 构造函数不是我们手动调用的,jvm虚拟机会在创建对象的时候主动调用构造函数 4 如果一个类,没有在代码中书写构造函数,那么java编译器会在编译的时候自动为类添加无参的构造函数 5 如果一个类,已经在代码中书写了构造函数,那么java编译器不会再在编译阶段自动给类添加无参的构造函数 6 构造函数可以在类中通过重载的方式存在多个

  我们在类中不手动书写构造函数的话,java编译器会自动添加构造函数,这个怎么来验证? 大家要注意,编译阶段和运行阶段的不同,javac命令是在编译java源代码文件,为了生成class类文件,java命令是启动jvm虚拟机,运行class文件。 javac命令编译出class文件以后,我们可以通过反编译工具,查看生成的class文件。 反编译class文件的命令: javap -c -l -private 类名 通过反编译,我们可以查看编译器是否为java类创建了构造函数

  如果我们手写了带参数的构造方法,编译器就不再生成无参的构造方法,这种情况下,我们通过 new Cat();就会失败。因为创建对象的时候,无法找到无参的构造函数。 如果想要不报错,就通过重载,同时提供有参和无参的构造方法。

  构造函数与普通函数的区别

  返回值类型的区别: 构造函数是没有返回值类型 的, 普通函数是有返回值类型的,即使函数没有返回值,返回值类型也要写上void。 函数名的区别: 构造函数的函数名必须要与类名一致, 普通函数的函数名只要符合标识符的命名规则即可。 调用方式的区别: 构造函数是 在创建对象的时候由jvm调用的。 普通函数是由我们使用对象调用的,一个对象可以对象多次普通 的函数, 作用上的区别: 构造函数 的作用用于初始化一个对象。 普通函数是用于描述一类事物的公共行为的。

 

构造代码块

  构造代码块的作用

  使用构造代码块,可以给对象进行统一的初始化操作。 与之对应的是,使用构造函数,可以对对象进行初始化操作。 举个例子:要求大家定义一个手机的类,每次创建一个手机对象,手机有自己的生产编号和型号名称。要求所有手机对象创建时候,都要进行一个产品测试,没有问题才可以出售。那么测试的工作每个对象创建时候都要调用。

  比如创建一个猫 class Cat{ String color; String name; Cat(String c,String n){ color = c; name = n; } } void main(){ //如果没有构造函数 Cat tom = new Cat();//如果定义了带参数的构造函数这里会报错,因为编译器不再自动生产无参数的构造函数 tom.name = "汤姆"; tom.color = "蓝色"; //如果有了构造函数,我们就可以 Cat tom = new Cat(“汤姆”,“蓝色”); }

  构造代码块的代码书写格式

  构造代码块的书写格式: { 执行语句 } 注意:构造代码块,必须写在成员的位置。不可以是方法的内部。

  大家看一段代码: class Cat{ //构造函数 public Cat(){ num = 10; } //成员变量 int num = 1; //构造代码块 { num = 5; } } void main(){ Cat c = new Cat(); println(c.num); } 最终输出多少? 在构造函数中,首先使用了变量num,会不会报错,因为没有声明? 我们可以反编译一下class文件,会发现是可以的。 构造代码块要注意的事项: 1. java编译器编译一个java源文件的时候,会把成员变量的声明语句提前至一个类的最前端。 2. 成员变量的初始化工作其实都在在构造函数中执行的。 3. 一旦经过java编译器编译后,那么构造代码块的代码块就会被移动构造函数中执行,是在构造函数之前执行的,构造函数的中代码是最后执行 的。 4. 成员变量的显示初始化与构造代码块 的代码是按照当前代码的顺序执行的。

  构造代码块的分类

  代码块的类别: 1. 构造代码块。 2. 局部代码块. 局部代码块,写在方法的内部,作用是可以让里面的变量提前释放,节省一点点空间。 3. 静态代码块 后面会详细讲解 

 

this关键字

  this关键字

  this关键字代表了所在函数的当前调用者对象。 使用this关键字的作用: 1 如果局部变量和成员变量同名的时候,使用this关键字可以区分成员变量和局部变量,默认就近访问局部变量。 2 在构造函数中可以调用另外一个构造函数,初始化对象。

  this关键字调用其他构造函数注意事项

  1. this关键字必须要位于构造函数中 的第一个语句。否则会报错 2. this关键字在构造函数中不能出现相互调用 的情况,因为是一个死循环。

  使用this关键字注意事项

  1. 存在同名的成员变量与局部变量时,在方法的内部访问的是局部变量(java 采取的是“就近原则”的机制访问的。) 2. 如果在一个方法中访问了一个变量,该变量只存在成员变量的情况下,那么java编译器会在该变量的 前面添加this关键字。

 

static关键字

  静态修饰符static

  1 static可以修饰成员变量 2 static可以修饰成员函数

  static修饰成员变量

  如果有数据需要被共享给所有对象使用时,那么就可以使用static修饰。 静态成员变量的访问方式: 方式1: 可以使用对象进行访问。 格式: 对象.变量名。 方式二: 可以使用类名进行访问。 格式: 类名.变量名; 注意: 1. 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。 2. 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候 才使用static修饰。 static修饰成员变量的应用场景: 如果一个数据需要被所有对象共享使用的时候,这时候即可好实用static修饰

  举例:定义一个会员类,统计当前有多少会员在线。

  static修饰成员函数

  static修饰方法(静态的成员方法): 访问方式: 可以使用对象进行访问。 对象.静态的函数名(); 可以使用类名进行访问。 类名.静态函数名字。 推荐使用是类名直接访问静态的成员。 静态函数要注意的事项: 静态函数是可以调用类名或者对象进行调用的,而非静态函数只能使用对象进行调用。 静态的函数可以直接访问静态的成员,但是不能直接访问非静态的成员。 原因:静态函数是可以使用类名直接调用的,这时候可能还没有存在对象, 而非静态的 成员数据是随着对象 的存在而存在的。 非静态的函数是可以直接访问静态与非静态的成员。 原因:非静态函数只能由对象调用,当对象存在的时候,静态数据老早就已经存在了,而非静态 数据也随着对象的创建而存在了。 静态函数不能出现this或者super关键字。 原因:因为静态的函数是可以使用类名调用的,一旦使用类名调用这时候不存在对象,而this 关键字是代表了一个函数 的调用者对象,这时候产生了冲突。 静态的数据的生命周期:静态的成员变量数据是优先于对象存在的。 static修饰函数的应用场景 如果一个函数没有直接访问到非静态的成员时,那么就可以使用static修饰了。 一般用于工具类型的方法 静态函数不能访问非静态的成员 静态函数只要存在有对象,那么也可以访问非 静态的数据。只是不能直接访问而已。

  静态代码块

  静态代码块 static{ 执行代码; } 静态代码块,会在类加载到内存的时候执行;而且只执行一次。使用静态代码块,可以对静态成员变量进行初始化操作,也可以调用静态方法。

  静态变量和非静态变量的区别

  1 作用上的区别: 静态成员变量的作用共享一个数据给所有的对象使用 非静态成员变量描述一个类公共属性 2 数量与存储位置上的区别 静态成员变量存在与方法区的内存中,而且只会存在一份 非静态成员变量存在与堆内存中,每个对象都有一份 3 生命周期的区别: 静态的 随着类的加载而存在,随着类文件的消失而消失 非静态 随着对象的创建而存在,垃圾回收机制回收而消失。

 

main函数详解

  代码: public static void main(Strings[] args){ System.out.println("Hello world!"): } public : 公共的。 在任何情况下都可以访问。保证让jvm在任何情况下都可以访问到main方法。 jvm也是个程序,它存在于JDK->bin->client->jvm路径下,如果是private修饰,出了类jvm就不能访问到,就不能调用执行main函数了。 static: 静态。可以让jvm调用main函数的时候不用创建对象。 static可以通过类名直接调用,这样jvm就不用创建对象了。如果不使用static,jvm也不好创建对象,因为类是开发者自己写的,如果不使用static,万一自定义了带参数的构造方法,会导致没有默认的无参构造方法,jvm又提前预料不到参数的类型和个数,就会无法执行。 void: 没有返回值。 main函数是由jvm调用的,如果main函数返回了,那么程序也就执行完了,jvm要这样的返回值没有意义。 main: 函数名。 main不是关键字,是jvm可以识别的特殊名字的函数。整个程序只有一个main函数 args(arguments):main函数的参数。可以在执行程序的时候通过main函数传参。 主函数传参。

 

单例设计模式

  设计模式概述

  设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。 模式就是解决一定问题的固定步骤。

  单例设计模式概述

  单例设计模式的目的:保证java程序在运行过程中,只有一个对象存在于内存中。 单例模式很重要,在编程过程中很多场合,都会使用到这种设计模式。比如音乐播放器等。

  单例设计模式的实现

  饿汉式

  代码实现步骤: 1 私有化构造函数 一旦私有化了以后,其他地方就不能创建对象了。 2 声明本类的引用类型变量,并且使用该变量指向本类对象 private static Single s = new Single(); 注意: a,使用private修饰,阻止类外进行访问 b,使用static修饰,这样在类被加载到内存以后,就会分配空间。而且共享。 3 提供一个公共的静态方法获取本类对象。 Public Static Single getInstance(){ return s; } 之所以使用static修饰,是因为私有化了构造函数,外部不可以创建对象。而且用public提供一个公共的接口允许外部访问该函数,获取唯一的单利对象。

  class Single{ private Single(){ } private Static Single s = new Single(); public Static Single getInstance(){ return s; } }

  懒汉式

  饿汉式模式有个缺点:类一旦加载到内存,就会创建一个对象。有可能程序运行到结束,都不会使用这个单例对象,这样就浪费了这个对象空间。所以我们可以使用懒汉式单例模式,在共有方法调用的时候再创建对象。 代码实现步骤: 1 私有化构造函数 2 声明本类的引用类型成员变量,但是不要创建对象。 private static Single s ; 3 提供公共静态的方法,获取本类的对象,获取之前判断是否已经创建了本类对象。如果已经创建了,那么直接返回对象即可。如果还没有创建对象,先创建对象,然后返回如果已经创建了对象。

  class Single{ private Single(){ } private Static Single s ; public Static Single getInstance(){ if (s == null) s = new Single(); return s; } }

  单例设计模式的实现的比较

  饿汉式和懒汉式都能实现单例模式 饿汉式在类加载后,就直接创建单例对象,如果一直不使用,就显得浪费空间;懒汉式等第一次调用共有方法的时候才创建对象,相对节省空间。 目前推荐大家使用 饿汉式,因为懒汉式目前存在线程安全方面的问题。如果多线程并发执行,可能会造成对象不唯一。

猜你喜欢

转载自www.cnblogs.com/yangzigege/p/8907639.html