Java小结3——面向对象进阶

目录

类就是设计图

构造器

this关键字

工具类

代码块

设计模式

final关键字的作用

常量

枚举

static关键字

成员方法的分类

方法的内存原理

抽象类

接口

接口新增的方法

多态

内部类

静态内部类

成员内部类

局部内部类(了解即可)

匿名内部类

常用API

Object类

StringBuilder

Math类

System类

Date类

两个小算法

Lambda表达式

包装类


面向对象复习补漏

类就是设计图

类就是建造对象的蓝图。

 定义类的注意事项:

  • 类名建议首字母大写。满足驼峰模式。
  • 一个java文件中可以定义多个类,但是只能有一个类是用public修饰的,public修饰的类名必须成为Java代码的文件名称。
  • 按照规范:建议一个Java文件只定义一个类。

构造器

 1.构造器的作用?

初始化类的对象,并返回对象的地址

2.构造器有几种,各自的作用是什么?

无参数构造器:初始化的对象时,成员变量的数据均采用默认值

有参数构造器:在初始化对象的时候,同时可以为对象进行赋值

3.构造器有哪些注意事项?

任何类定义出来,默认就自带了无参数构造器,写不写都有。

一旦定义了有参数构造器,无参数构造器就没有了,此时就需要自己写无参数构造器了。

this关键字

this关键字出现在成员方法、构造器中、代表当前对象的地址。用于指定访问当前对象的成员变量、成员方法。

this关键字小结

 面向对象的三大特征:封装、继承、多态。

  • 封装:解决属性和方法属于哪个对象的问题。
  • 封装步骤:通常将成员变量私有、提供方法进行暴露。
  • 封装作用:提高业务功能设计的安全性提高开发效率

特征的含义:

  • 所谓特征指的是已经成为Java设计代码的基本特点,即使毫无意义,通常也要需要满足这样的设计要求来编写程序。

如何进行更好的封装?

  • 一般会把成员变量使用private隐藏起来,对外就不能直接访问了。
  • 提供public修饰的getter和setter方法暴露其取值和赋值。

标准JavaBean

  • 也可以理解成实体类,其对象可以用于在程序中封装数据。

Java中书写标准JavaBean必须满足如下要求:

  • 成员变量使用private修饰。
  • 提供每一个成员变量对应的setXxx()/getxxx()
  • 必须提供一个无参构造器

工具类

 为什么工具类中的方法不用实例方法做?

  • 实例方法需要创建对象调用。
  • 此时用对象只是为了调用方法,这样只会浪费内存。

工具类定义时的其他要求:

由于工具里面都是静态方法,直接用类名即可访问,因此,工具类无需创建对象,建议将工具类的构造器进行私有化

 小结

 

代码块

 作用:

初始化静态资源

初始化实例资源

 

案例:制作一副扑克牌

 放到main里也可以,但是这种静态代码块的写法更专业,彰显牛逼

设计模式

什么是设计模式(Design pattern)

  • 开发中经常遇到一些问题,一个问题通常有n种解法的,但其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式。
  • 设计模式有20多种,对应20多种软件开发中会遇到的问题。
  • 学设计模式主要是学2点:

>第一:这种模式用来解决什么问题。

>第二:遇到这种问题了,该模式是怎么写的,他是如何解决这个问题的。

单例模式

·可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象。

·例如任务管理器对象我们只需要一个就可以解决问题了,这样可以节省内存空间。

饿汉单例,设计步骤:

创建一个类,把构造器私有,外部不可以创建新对象。

定义一个静态成员变量来存储对象。

l包是用来分门别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护

l建包的语法格式:package 公司域名倒写.技术名称。包名建议全部英文小写,且具备意义

package com.itheima.javabean;
public class Student {

}

建包语句必须在第一行,一般IDEA工具会帮助创建

导包

  • 相同包下的类可以直接访问,不同包下的类必须导包,才可以使用!导包格式:import包名.类名;
  • 假如一个类中需要用到不同类,而这个两个类的名称是一样的,那么默认只能导入一个类,另一个类要带包名(全名)访问

什么是权限修饰符?

  • 权限修饰符:是用来控制一个成员能够被访问的范围
  • 可以修饰成员变量,方法,构造器,内部类,不同权限修饰符修饰的成员能够被访问的范围将受到限制。

权限修饰符的分类和作用范围

 学完权限修饰符需要具备如下能力

  • l能够识别别人定义的成员的访问范围。
  • l自己定义成员(方法,成员变量,构造器等)一般需要满足如下要求:
  1. 成员变量一般私有
  2. 方法一般公开
  3. 如果该成员只希望本类访问,使用private修饰。
  4. 如果该成员只希望本类,同一个包下的其他类和子类访问,使用protected修饰。

final关键字的作用

final 关键字是最终的意思,可以修饰(类、方法、变量)

  • l修饰类:表明该类是最终类不能被继承。一般不用,工具类可以加final,使用的不是继承的。
  • l修饰方法:表明该方法是最终方法,不能被重写。一般不加,//TODO
  • l修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)

补充:变量分为局部变量(初始化一个值后续不可修改)

成员变量,成员变量又分为

实例成员变量(几乎不用,会导致所有实例的数据一样的)

静态成员变量。

final修饰变量的注意

  • final修饰的变量是基本类型:那么变量存储的数据值不能发生改变
  • final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的。

常量

  • 常量是使用了public static final修饰的成员变量,必须有初始化值,而且执行的过程中其值不能被改变
  • 常量名的命名规范:英文单词全部大写,多个单词下划线连接起来。
  • 常量的作用:通常用来记录系统的配置数据

 使用常量做信息配置的优势

  • 在编译阶段会进行“宏替换”:把使用常量的地方全部替换成真实的字面量。相当于不再重新使用常量来替换,直接用字面值。
  • 维护系统容易,可读性更好。

案例说明:

现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号(上下左右),以便控制玛丽移动的方向。

选择常量做信息标志和分类:

代码可读性好,实现了软编码形式。

 相比于在程序中使用1234,使用常量来做信息标志,使程序的可读性可维护性更好。类比#define

枚举

public enum Season {
//第一行必须罗列枚举类的对象名称,建议全大写
SPRING, SUMMER, AUTUMN, WINTER;
}

反编译之后:

枚举的特征:

  • 枚举类都是继承了枚举类型:java.lang.Enum
  • 枚举都是最终类,不可以被继承。
  • 构造器都是私有的,枚举对外不能创建对象。
  • 枚举类的第一行默认都是罗列枚举对象的名称的。每个对象名称都是常量,写四个对象就只有四个对象。
  • 枚举类相当于是多例模式。

案例说明:

现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号(上下左右),以便控制玛丽移动的方向。

选择常量做信息标志和分类:(实际开发中这种方式相对更多)

虽然可以实现可读性,但是入参值不受约束,代码相对不够严谨。

枚举做信息标志和分类:

代码可读性好,入参约束严谨,代码优雅,是最好的信息分类技术!建议使用!

switch已经兼容枚举,可以直接读取枚举类型。

static关键字

  • static是静态的意思,可以修饰成员变量和成员方法
  • static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改

 

静态区的变量各个成员实例都可以访问  

 

成员方法的分类

静态成员方法(有static修饰,归属于类),建议用类名访问,也可以用对象访问

实例成员方法(无static修饰,归属于对象),只能用对象触发访问

 对象自己用的方法定义成实例方法,共用性的方法定义成static方法

小结 

 

方法的内存原理

第一步,将类和静态方法加载到方法区,

第二步,将main提到栈区跑,此时可以直接调用其他static方法,

第三步,创建实例,放入堆内存,访问方法区,可以调用静态和对应的非静态方法。

static使用注意事项

  • 静态方法只能访问静态的成员,不可以直接访问实例成员。
  • 实例方法可以访问静态的成员,也可以访问实例成员。
  • 静态方法中是不可以出现this关键字的。

抽象类

抽象方法,不实现,只作方法签名,不声明方法体。

一个类里如果有抽象方法,这个类也要声明为抽象类。

派生出子类,要子类去完成这个方法

  • 抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承。
  • 当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以声明成抽象类。

也可以定义一些子类通用的实例变量,提升代码复用性

抽象类小结

 注意:

  • 类有的成员(成员变量、方法、构造器)抽象类都具备
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。(实际应用中这一条很少见)
  • 不能用abstract修饰变量、代码块、构造器。
  • 抽象类不能创建对象,即使内部没有抽象方法的抽象类也不能创建对象!

final和abstract有什么关系?

互斥关系:

final修饰的类不能被继承,abstract修饰的类往往需要被继承并实现方法。

修饰的方法同上,一个不能被重写,一个必须被重写。

模板方法

什么时候使用模板方法模式?

  • 使用场景说明:当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候。

模板方法模式实现步骤:

  • 把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。
  • 模板方法中不能决定的功能定义成抽象方法让具体子类去实现。

案例,写作文

标题和首尾段是确定的,要求不同的学生类自己发挥正文部分

 中学生类继承学生类,来实现具体的写正文方法

使用时:调用父类模板方法,遇到抽象的writemain(),再调子类的具体实现的方法。

 注意:模板方法应该用final来修饰,使其不能被重写。

接口

就是一种规范,约束必须要这么做,且一定是公开public的。

由于接口体现规范思想,必须公开,所以代码中public abstract可以省略。

接口与类的关系:

接口是用来被类实现(implements)的,实现接口的类称为实现类。实现类可以理解成所谓的子类。

一个类只能继承一个父类,但可以同时实现很多个接口。

接口多继承:一个总接口继承其他很多的接口,实现类只需要继承这个总接口即可

接口新增的方法

JDK8之后,接口新增3个方法。可以直接在接口中定义带有方法体的方法,便于实现类直接获得,方便扩展。

默认方法实际上就是实例方法,用实现类的实例对象来调用。用得不多,为看源码做准备。

只能接口名自己调用Interface.inAddr();

JDK9之后才有的私有方法

技巧:在project struture里修改JDK版本,可以查看该版本是否支持某项技术

 外部不可用,为接口中的其他方法所用。

接口的注意事项:

  • 接口不能创建对象,它是抽象中的抽象
  • 一个类实现多个接口,多个接口的规范不能冲突
  • 一个类实现多个接口,多个接口中有同样的静态方法不冲突。

只能A接口调A的静态方法,B接口调B的静态方法。

  • 一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法默认用父类的

class Cat extends Animal implements Creature { }注意只能先extens,再implements

  • 一个类实现了多个接口,多个接口中存在同名的默认default方法,可以不冲突,这个类重写该方法即可。
  • 一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。

多个接口的抽象方法不一致,比如一个返回String ,一个返回Void。

总结:

定义接口,实现功能,项目中的软件解耦。

多态

多态重点:编译看左边,运行看右边。编译阶段对象属于父类类型,运行调方法时实际上还是子类的方法。

 劣势:多态形式下,不可以调用子类独有的方法(如果要用需要强转)

 调用前可以使用强转,再使用子类方法。

强转之前最好用instanceof判断类型,得到其真实类型。

内部类

 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计。

  • 内部类通常可以方便访问外部类的成员,包括私有的成员。
  • 内部类提供了更好的封装性,内部类本身就可以用private、protectecd等修饰,封装性可以做更多控制。

重点:匿名内部类

静态内部类

 在创建对象的时候,需要带上外部类的类名

静态内部类可以访问所在外部类的静态成员变量

不可以访问外部类的实例成员变量

静态内部类小结

成员内部类

 

 创建方式要注意,要先把外部类给new出来之后,再紧跟着new内部类:new Outer().new Inner()

注意:

1、成员内部类中是否可以直接访问外部类的静态成员?

可以,外部类的静态成员只有一份可以被共享访问

2、成员内部类的实例方法中是否可以直接访问外部类的实例成员?

可以的,因为必须先有外部类对象,才能有成员内部类对象,所以可以直接访问外部类对象的实例成员。

 成员内部类变量访问范围的Demo

 show方法里的局部变量可以直接访问,内部类中的成员变量要加this访问,所属的外部类的成员变量加 类名.this来访问。

局部内部类(了解即可)

 写法很奇怪

 

匿名内部类

  • 匿名内部类是一个没有名字的内部类。
  • 匿名内部类写出来就会产生一个匿名内部类的对象。
  • 匿名内部类的对象类型相当于是当前new的那个的类型的子类类型。

匿名内部类用法,抽象类本来不可以创建对象,但是加一对大括号{}马上重写其方法,就可以实现简化代码,不需要再创建一个子类继承该抽象类。可以说是类和对象混合在一起。

注意:这个对象a是匿名内部类(继承Animal)的对象,而不是接口的对象。

简化代码:直接将匿名内部类对象作为方法的入参,参考Btn按钮的setOnClickListener里的new OnClickListener

 

常用API

Object类

 toString()直接用是没意义的,需要重写来打印内容。

equals( )

默认比较两个对象的地址,一般需要子类重写,来比较内容。

注意:字符串用equals来比较是比较内容的。而用"=="是比较地址的

小结:

 Objects的equals方法,会先做一层非空校验。比直接用object的equals更安全,因为equals传入null的话,会有空指针异常。

 小结

StringBuilder

  StringBuilder提供的常用api方法:

StringBuilder的append方法拼接完之后,又返回了同一个this对象,所以支持链式编程。

 注意,其reverse方法,反转的是本字符串的所有内容,而不是以每次append作为基本单位。

 //"国中你爱我cba110"

注意:StringBuilder只是拼接的手段,最后的目的还是要恢复成String类型的对象。

StringBuilder效率高的原因

小结:

 Demo:用StringBuilder来输出整型数组的内容:

 代码风格学习:结尾处用三目运算符来一步兼容中间符号插入和结尾处理,注意右中括号不可以放在循环里,否则空数组的情况只会打印一个左中括号。

Math类

工具类,没有构造器,不能创建对象,内部的方法均为静态static方法

常用:random,取绝对值,,,,等等。

 random方法,生成0-1之间的随机数,含0不含1,如果要生成其他区间,可以以此为基础来变通。

System类

第一个终止当前虚拟机,慎用!

 第二个获取系统当前时间,从1970年1月1日(纪念C语音的生日)开始计算,到某一时刻的毫秒值。可以用作性能分析,在某一板块开始和结束时都获取一下当前时间作差,得到程序运行耗时

arraycopy,数组复制,参数很多,建议用的时候看源码,对应填入参数。

BigDecimal

解决浮点型运算精度失真问题,后续用到再学习,黑马视频强化课,day3最后一个视频。

Date类

无参构造器或者long型的有参构造器,传入毫秒值。

时间格式化的方法

两个小算法

选择排序

选择排序的思想

·每轮选择当前位置,开始找出后面的较小值与该位置交换。

选择排序的关键

·确定总共需要选择几轮:数组的长度-1.

·控制每轮从当前位置为基准,与后面元素选择几次。

 二分查找

只适用排好顺序的数组,性能较好。

 

 

 

小结:

Lambda表达式

  • Lambda表达式是JDK8开始后的一种新语法形式。
  • 作用:简化匿名内部类的代码写法。

 只能简化函数式接口的匿名内部类

什么是函数式接口?

  • 首先必须是接口、其次接口中有且仅有一个抽象方法的形式
  • 通常我们会在接口上加上一个@Functionallnterface注解,标记该接口必须是满足函数式接口。

例子:

 小结

 Lambda进一步省略代码:

Lambda表达式的省略写法(进一步在Lambda表达式的基础上继续简化)

  • 参数类型可以省略不写。
  • 如果只有一个参数,参数类型可以省略,同时()也可以省略。
  • 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写,同时要省略分号!
  • 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写。此时,如果这行代码是return语句,必须省略return不写,同时也必须省略";”不写

注意:简化不要强行过度简化,保留一些代码可读性。

包装类

int 变成Integer,char变成Character,其他类型均是首字母大写。

 第二条用的不多,可以直接使用 基本类型+""

第三条用得很多,将字符串转换成其真实的类型。

 要转成什么类型就调对应包装类的方法。

或者直接用ValueoOf方法

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值