概述
六、数组
问题:如何存储一个班所有的同学名字?可以用变量存储吗?不行,怎么办?使用数组存储
6.1 数组
6.1.1 概念
— 是同类元素的集合,在内存上是一系列连续的区间(画图说明)
6.1.2 数组两种定义方式
-
动态初始化
- 类型[] 数组名 = new 类型[length]; 如 String[] arr = new String[3];
- 注意:new --内存分配操作符,在堆内存中给数组分配空间
- 动态初始化时,根据类型默认元素的值为 0、0.0、false、null(引用数据类型)
- 类型[] 数组名 = new 类型[length]; 如 String[] arr = new String[3];
-
静态初始化
- 类型[] 数组名 = {值1,值2,…} 如 int[] arr ={1,2,3,4};
- 类型[] 数组名 = new 类型[] {元素1,元素2,…} ,如arr =new int[]{2,4,6};
-
注意:
- length --数组的长度
- index --数组下标
- arr[index] --取某一个数组元素
- 数组元素类型必须一致,可以存放引用类型和基本数据类型
- 数组下标越界 --原因:当数组初始化以后,数组长度固定,当访问的下标在数组中不存在
6.1.3 数组遍历
- for循环遍历 for(int i =0;i<arr.length;i++){}
- foreach遍历 for(元素类型 当前元素:数组名){}
作业:
- 定义一个数组,求出最大值和最小值
- 判断一个数是否是回文数,如12321
6.1.4 二维数组的定义
-
定义:实际是数组里存放数组
-
动态初始化: 数组类型 [ ] [ ]数组名称 = new 数组类型[长度] [ (列数)]
-
如 int[] [] a1 = new int[3] [ ];
-
int[ ] [ ] a1 = new int[3] [4];
-
int[] [] a1 = new int[ ] [4];//错误 ,必须声明长度
-
-
静态初始化:
- 数组类型[ ] [ ] 数组名称 = new 数组类型[ ] [ ]{{1,2},{3,4,5},{6}}
- 数组类型[ ] [ ] 数组名称 = {{1,2},{3,4,5},{6}}
-
遍历:嵌套循环
for (int i = 0; i < arr.length; i++) { // 遍历二维数组个数 for (int j = 0; j < arr[i].length; j++) { // 遍历元素(数组)个数 System.out.println(arr[i][j]);// 打印数据 } }
6.1.5 冒泡排序
冒泡排序原理:每一轮结束后,最大的元素放最后,且下一轮都会减少一个元素参与比较
....
int[] arr ={200,4,11,23,1,12};
int temp;
for (int i = 0; i < arr.length-1; i++) {//轮数
for (int j = 0; j < arr.length-i-1; j++) {
if (arr[j] >arr[j+1]) {
temp =arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
再重新遍历数组arr即可
升序排序
6.1.6 工具类使用
-
Arrays.sort(数组名) --底层冒泡,只能升序,如 Arrays.sort(str);
-
Arrays.toString(数组名) --转为字符串
-
Arrays.fill(数组名,值) --填充数组 如 Arrays.fill(arr, 10);
-
Arrays.equals() --比较两个数组内容是否相同 注意:== 对于基本数据类型,比较是值本身,引用类型比较是地址编号 如 Arrays.equals(c1, c2);
-
数组拷贝
- Arrays.copyof(原数组,个数) – 方法内部已创建数组,如int[] a = Arrays.copyOf(src, 2);
- System.arraycopy(数组A,起始位置,数组B,起始位置,个数) --复制内存效率更高,如 System.arraycopy(src, 2, dest, 0, 4);
七、面向对象
7.1 理解面向过程和面向对象思想
7.1.1 面向过程设计思想
- 提问:从家到公司怎么过来的?
- 面向过程设计思想含义: 重心是过程,做一件事情,有多个步骤(过程),每个步骤之间是有既定的顺序,最后按照顺序完成即可
- 优点:代码结构比较清晰,容易理解,不足:对于类似淘宝、王者荣耀等业务非常复杂,代码量很庞大,不能一个人完成,如果使用面向过程的思想来设计,有N步骤,需要M个人来完成,不方便团队协作,代码维护难
7.1.2 面向对象设计思想(OOP -Object Oriented Programming)
1.现实中例子:造车
问:同一类的车,如何制造出来的呢? --图纸
图纸 -----------------------------------------------> 具体的车
抽象的(类) 具体的 看的见摸得着(对象,多个相类似的车在一起,归一类)
类和对象关系
类 -----------------------------------------------------> 对象
创建过程(按照图纸生产)
对象 ----------------------------------------------------> 类
抽象过程(研究别国的汽车,抽象出国产汽车的图纸)
问:制造一辆具体的BMW mini车
mini车图纸 ----------->造车(需要很多零部件如发动机、轮胎、座椅等)
造发动机 ---->图纸
造轮胎 ---->图纸
轮胎内部又需要橡胶 -->橡胶图纸
造车窗 ---->图纸
最终发现:制造一辆车,首先需要图纸,图纸中反映出很多零部件,每个零部件生产也需要图纸(类),只要有了图纸就能产出具体的产品,当发动机、轮胎、座椅等零部件制造好以后,最终造成就变成了零部件(对象)的组装,如果哪天轮胎坏了,只要换轮胎就可以了,车的维护就很简单。
现实生活中,造车就是一种面向对象(零部件)的设计思想,程序来源于生活,在程序中如何实现面向对象呢?
2.程序中例子 : 淘宝网站
商城网站 淘宝购物网站
图纸 具体的一个产物
网站中细分功能:
产品类别 ----图纸
商品 —图纸
购物车 –
买家中心
评论区 …
采用这种面向对象的设计思想,每个组件由一个小团队完成(便于分工),彼此不冲突,相互协作,出现问题,找到对应的组件即可。
7.2 类
7.2.1 类
-
含义:在java中,类是程序的最小组织单元,是抽象的,是一种引用数据类型,也是一种数据封装机制和类型定义机制
-
类的三要素:
- 类名 --英文单词,首字母大写 如汽车类Car 学生类Student
- 静态特征 --属性 如:狗类 名字 年龄 体重等
- 动态特征 --行为或方法 如跑 、吃等
-
类的几个说明:
- 类名、属性、方法的命名规范
- 类中属性和方法成员:关注业务相关
- 类的设计原则:单一原则(高内聚低耦合)
- package:用来管理类
- 包的定义规范:全部英文且小写 如当前包 package day5.modifier;
- 公司域名倒着写 +项目名称+功能模块名称,如 org.w3c.dom
- 导包:import java.util.*; import java.util.Scanner;
- import static java.util.Arrays.*; --直接导入类Arrays中的方法,在程序中使用时,不用写类名,直接使用其中的方法
- 当多个包下有同名类时,避免冲突,使用时直接包名+类名 如 java.sql.Date
-
Dog测试类的内存分析图
public class Dog { //Dog类 //静态特征:属性 成员属性 String name; int age; double weight; //动态特征:方法 行为 public void eat(){ //内部实现细节 System.out.println("吃骨头.."); }
public class TestDog { //测试类 public static void main(String[] args) { int i = 10; //创建一个对象 // 类型 对象名 = new 类型(); Dog dog = new Dog(); //访问一个对象中属性 .点位符 优先级高于括号 System.out.println(dog.name); //null //给狗起名字 对象给属性赋值 对象名.属性名 = 值 dog.name = "旺旺"; System.out.println(dog.name); //访问方法 dog.eat(); } }
内存分析图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJ2XIkRY-1611664282556)(C:UsersnjwbDesktopimgjava对象内存分析.png)]
-
类和对象的关系
- 类是抽象的,对象是具体的,是类的一个实例
- 类中的属性也叫对象属性或实例属性、成员属性
- 类中的方法也叫对象方法或实例方法、成员方法
- 通过对象可以抽象出类
7.3 引用类型
相对基本数据类型而言,在栈内存中,引用数据类型存储的是地址编号,而基本数据类型存储是具体的数值
7.4 方法
例: 设计一个类:榨汁机,有一个功能是榨汁功能。
-
语法:
修饰符 返回值类型 方法名(参数列表) 异常类型 {// 方法体 实现某一功能的代码块;}
-
访问修饰符:public protected 默认 private
-
返回值类型:
- void --该方法无返回值
- 基本数据类型 --返回具体的值
- 引用数据类型 --返回引用地址
-
方法名称 --动词 驼峰命名法
-
参数列表
- 如果无参数,即方法名()
- 若有参数 如方法名(参数1,参数2,…,参数n)
案例:
-
用面向对象思想来重构人机猜拳游戏
-
分析需求,找到程序中的要研究的对象
游戏
人的玩家 ----程序中的组件
计算机玩家
-
根据对象抽象出类
游戏对象 —游戏类
人的玩家 --人玩家类
计算机玩家 --计算机类
-
分别完成类中的属性和方法(和业务相关)
人的玩家 PersonaPlay{
属性:姓名 分数
方法:出拳
}
测试PersonPlayTest类
计算机玩家 ComputerPlay{
属性:姓名 分数
方法:出拳
}
测试ComputerPlayTest类
游戏类Games{
属性: (体现数据)
对战次数
计算机玩家
真人玩家
方法:
(体现功能)
输出游戏的启动界面
游戏初始化
开始游戏
统计单局游戏的胜负情况
统计游戏的数据
统计整个游戏的胜负情况
}
粗粒度:宏观角度,大致将程序分为几块
细粒度:微观角度,每个小块中有没有独立的功能,如果有则可以进一步抽取
-
-
设计一个计算器,支持多个整数相加(至少两个参数) --数组 可变参数
//可变参数 类型 ... 变量名 public int add(int ... numbers){ int cale =0; for (int i = 0; i < numbers.length; i++) { cale +=numbers[i]; } return cale; }
-
设计一个计算阶乘的方法(递归算法)
//递归算法 public int cale(int n){ if (n== 0) { System.out.println("输入参数有误!"); return 0; }else if (n == 1) { return 1; }else { return n*cale(n-1); } }
-
7.5 构造方法
需求:假设开一家宠物店,里面有狗、企鹅等 ,需要把狗的信息录入系统中,狗
属性: 名字、品种、性别、健康程度
方法: 自我介绍
1 含义:
也叫构造器、构造函数,专门用于创建对象,并给对象中的属性赋值,任何类中默认有个无参构造方法。
2 语法: 权限修饰符 方法名(参数列表) {…}
注意:
- 是一种特殊方法,无返回值类型
- 方法名和类名必须一致
- 系统默认提供无参构造方法(隐式),如果想定义有参构造方法,则系统不会再提供无参构造方法
7.6 方法重载
-
含义: overload,一个类中定义多个同名的方法,但参数列表不同
-
满足三个条件
-
方法名必须相同
-
参数列表必须不同(个数、类型、位置顺序)
-
和权限修饰符、返回值类型无关
-
-
使用场景 --类中有多个功能一样,参数略微不同 jdk中有很多
//无参构造器 public Dog(){ System.out.println("我是无参构造器"); } //有参构造器 public Dog(String name, String strain, String sex, int health) { super(); this.name = name; ... }
练习:设计一个自己的数学类,支持两个整数相加或三个整数的相加
7.7 this关键字
-
出现原因:为了解决这种参数名和属性名一样而造成的混淆不清,提供了this这个关键字
-
this --指的是当前对象
-
this. 属性或方法名() – 调用当前对象的属性或方法
-
this() 或this(参数列表) – 调用无参构造或有参构造
- 注意:在构造方法调用其他构造方法,this()必须放在第一行
- 使用快捷键自动生成 alt +shift + s或右键 属性 构造方法(无、有)普通方法
7.8 面向对象的三大特征–封装性
1.1 原因
客户端调用一个对象,如果直接通过对象.属性去操作对象中的数据,可能会注入一个非法数据
,造成系统不安全,应该要屏蔽这种方式调用,提供另外一种方式来访问对象中的属性。
1.2 步骤
-
设置属性私有化 private
-
提供公共的访问方法和修改方法
-
get命名规则:返回值类型跟属性一致,名字getXxx,没有参数 ,对于boolean型属性,其名字一般为isXxx
-
set命名规则: 无返回值,名字为setXxx ,参数为属性的类型
-
-
在set方法中加入访问控制语句
-
1.3 作用
1. 提高数据的安全性
2. 提高代码复用性,使代码设计更加细粒度化。
7.9 常量
设计企鹅类(Penguin): 姓名 性别 区域 健康度 自述功能
注意:性别这块用常量表示
1 .1 含义:
就是固定的,不能改变的量。只能用,不能修改, 如final String gender =“Male”;
注意:
-
final修饰的基本数据类型,值不能改变,修饰引用数据类型,不能重新new对象
-
final和static关键字连用,叫静态常量,属性命名必须是大写 ,下划线分隔,如 static final String FEMALE_SEX= “Female”;
-
static 修饰类中属性,叫静态属性或类属性、类成员,类名.属性名(推荐)或对象名.属性名
public static void main(String[] args) {
Constant cons = new Constant();
System.out.println(cons.FEMALE_SEX); //对象名.属性
System.out.println(Constant.FEMALE_SEX);//类名.属性 推荐使用
}
7.10 面向对象三大特征 – 继承
宠物店生意越来越好,做了一个调查问卷,客户说想增加猫、猪、老鼠、兔子等…
看之前的程序设计方式,有什么不妥的地方?
-
单一原则(高内聚低耦合)
-
开闭原则
-
开:对扩展开放, 系统在扩展功能时,需要写更少代码即可,提高系统的扩展性
-
闭:对修改封闭,在程序设计中,如果功能发生变化了,忌讳修改大量代码,只修改局部,不影响大局即可
-
对比狗和企鹅的代码有重复的代码
解决重复代码可以用继承解决
现实生活中,继承包含几个角色: 父亲 子女 孙子辈 像族谱
程序中 , 父类 子类 子类的子类
代码编写:Pet类 和Pig类
1 继承***
含义:以已经存在的类作为基础建立新类的一种技术,
注意: 1.是一种单继承关系
2.如果没有指明具体的父类,默认继承Object类 (超基类)
语法 :public class 子类 extend 父类{},如public class Dog extend Pet {}
2 继承范围***
–子类可以继承父类的属性和方法等除以下,反之,父类不能访问子类自己定义的属性和方法
- 父类的私有属性和方法不能被访问
- 父类的构造方法不能被继承,如Dog dog = new Pet(); //错的
- 父类使用的默认修饰符,其他包中的子类不能被继承
3 四大访问修饰符***
private: 作用于本类内部 权限最小
默认权限: 同包中,本类、其他类(子类)
protected: 同包中,本类、其他类(子类),不同包中,子类
public :权限最大
4 子类对象初始化过程***
创建对象时,会给属性赋值(对象初始化)
创建子类对象时,会发生什么呢?
前提:给父类和子类无参构造器中设置打印一段信息,测试子类
***结论: 创建子类对象时,默认先调用父类的构造方法,先创建父类的对象,虽然没有直接调用父类构造器,但是子类中有个隐式的调用
public Dog(){
//显示调用
super();
System.out.println("dog子类无参构造方法");
}
子类对象调用整个初始化过程
子类 对象名 = new 子类();
- 父类的属性赋值
- 父类构造方法
- 子类属性赋值
- 子类构造方法
注意:
- 在继承中,如果父类只设置有参构造,没有设置无参构造,子类构造通过super()显示,提示调用父类哪种参构造方法,否则会编译报错:Implicit super constructor Pet() is undefined. Must explicitly invoke another constructor
- 如果父类不设置有参构造方法,则隐式调用父类中无参构造。
- 父类设置有参构造,必须设置无参(系统不提供),子类中有参调用有参,无参调用无参
5 super用法
super --指父类对象 this --指当前对象
super() --子类调用父类的无参构造
super(参数) --子类调用父类的有参构造 且只能放第一行
super.属性名或方法 --调用父类的成员属性或方法
System.out.println(getName());//子类继承
System.out.println(this.getName());//子类继承即本类中的方法
System.out.println(super.getName());//调用父类的方法
注意:
- 如果子类中,有一个方法,是从父类中继承过来,三种都可以使用,super.getName() 可读性高
- 使用场景:如果父类和子类中有同样的方法,但是这两个方法的实现不一样(方法重写),需要区分是父类还是子类
//在子类中定义一个方法add
public void
add(){
super.show(); //调用父类
this.show(); //调用子类
}
6 方法重写(override)***
方法重载(overload)是什么?
6.1 重写满足条件:
- 继承关系 如Pet和Dog、Penguin
- 父类的方法不满足子类的需求,需要将父类的方法重新实现,如show()方法
6.2 概念
也叫覆盖,override, 在子类中重新定义父类已经存在的方法如show()
6.3 特点
- 方法名、参数列表(个数、类型、顺序)和返回值类型,必须和父类一样
- 重写方法的权限大于等于父类方法的权限
- 子类方法中所抛出的异常是父类的一个子集
7 抽象类和抽象方法
问:给宠物系统扩展吃的功能
只要在父类中添加吃的方法
那么具体的子类,如狗啃骨头, 猪吃粗食 猫吃老鼠…必然要重写父类方法
父类宠物吃啥?不确定,pet中eat方法不好实现 ,也没有意义
–》可以把父类的eat方法声明成抽象方法(abstract修饰,无方法体 )
–》那么此类中有抽象方法,则必须是抽象类(abstract修饰,无构造方法)
–》子类继承抽象类,必须重写抽象方法,除非子类也是一个抽象类
1.1 什么是抽象类?
被abstract修饰的类
1.2 什么是抽象方法?
被abstract修饰方法,且没有方法体,注意:抽象方法不能被static、final、private、native和synchronize关键字修饰
1.3 特征
- 可以有抽象方法,也可以没有
- 可以有具体方法
- 可以有构造方法
- 不可以new对象
- 有抽象方法的类,肯定是抽象类
1.4 使用场景
- 当一个类中有一个方法无法实现时,可以使用抽象方法表示,这个类必须是抽象类,要求子类来实现
- 当一个类中没有抽象方法,声明了抽象类,不能被实例化,要求子类实现
8 final用法
1.1 修饰属性:
当做常量,基本数据类型,值不能被修改,引用数据类型:不能被重新实例化,但对象中的数据域可以改变
1.2 修饰类:
终结类,不能被继承 如jdk中 String类 Integer类
1.3 修饰方法:
不能被重写
9 static用法***
1.1 修饰属性
叫静态属性、静态变量、类变量,直接通过类名.属性调用
和final 修饰属性,叫静态常量 如final static String FEMALE_SEX = “Female”;
1.2 修饰方法
叫静态方法、类方法,直接通过类名.方法名调用
注意:
- 静态方法或静态属性不能调用非静态方法或属性(产生时机早),反之则可以
- 使用场景:把工具类的方法设计成静态方法***
1.3 修饰代码块 static{ 代码块}
含义:
叫静态代码块,在类加载到方法区中,当类对象产生时,会优先执行且只加载一次,初始化作用
在静态代码块中,属于类级别的,不能引入非静态成员属性或方法(产生时机最早)
区别:
- 初始化块,在类内部,用于初始化对象相关内容,在产生对象后会自动执行,在构造方法之前。如{初始化块}
- 局部代码块,在方法内部,用于提前释放不使用的栈内存 {int a =1;}
1.4 修饰类(静态内部类,不做了解)
补充:对象产生的过程
- 读取class文件产生类对象,这一过程叫类加载
- 给静态变量赋初值
- 执行静态代码块
- 产生对象,给成员变量赋初始值
- 执行初始化块
- 执行构造方法
10 变量作用域
1.1 局部变量
作用域在方法或代码块里,必须要先赋值后使用
1.2 全局变量
作用于类中,属性不需要赋值可以使用(默认值)
细分为对象属性(堆中)和类属性(方法区),对象属性共享类属性值
11 继承总结
1.1 作用:解决代码冗余度
1.2 使用场景:
- 多个类中有共同的属性和方法
- 满足 is a 关系 如 dog is a Pet ,penguin is a Pet
7.11 面向对象三大特征 -多态***
生活中的多态(多个状态):同一个事物,在不同条件下,对外界展示的形态也不一样
如水 100度 :气体 0 度下:固体 常温:液体
同学 教室: 学生 家里:子女 街上:潮男潮女
1 含义
引用类型变量指向其子类的对象(即向上转型)为前提,该变量在访问方法时,访问是该变量所指向的实际类型对象中的方法,多态也叫动态绑定,或运行时绑定,原理:当虚拟机调用一个实例方法时,它会基于对象实际类型(只能是运行时获取实际类型)来选择所调用的方法。
注意:
- 属性没有多态性
- 多态的实例不能访问子类特有的方法和属性
2 前提
- 继承
- 重写方法
- 父类引用指向子类对象(向上转型)
package day6.polym;
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.say();
//父类引用指向子类对象
Person p = new Student();
p.say(); //编译器认为 p是Person类型对象 ,运行时才会找具体的实例对象
System.out.println(p.age); //age没有继承性
22
//p.show(); //不能访问子类私有方法
}
}
3 作用
- 提高代码的扩展性
- 代码的可插拔性
- 降低代码的冗余
4 类型转型和instanceof
-
自动转换
- 基本类型 double d = 6;
- 引用类型 父类 对象 = 子类对象 --向上转型
-
强制转换
基本类型:int a = (double)3.14;
引用类型:子类 对象 =(强制类型转换)父类对象 --向下转型(前提向上转型否则报类型转换错误)
-
instanceof用法:
对象 instanceof 类: 判断一个对象是否是一个类(其子类)的实例
public static void main(String[] args) {
double d =20.0;
int b = (int) d;
System.out.println(b);
//向上转型
Person p = new Student();
//向下转型的前提是先向上转型
否则报运行时异常
java.lang.ClassCastException
Student stu
= (Student)
p;
stu.eat();
if (p instanceof Student) {
Student student
=(Student) p;
student.eat();
//把p转为student对象就可以访问私有方法了
}
}
7.12 接口***
原因:面向对象的三大特征继承和多态都是和继承有关系,而java中只支持单继承,一个类继承某个类就不能继承其它类,而java中没有多继承,使用接口来代替
接口和类是同一级概念(程序最小组织单元)
生活中:USB接口 (厂家标准:规定USB接口2.0或3.0 长 宽 额定电压等) 是一种标准 实际上不工作
U盘、键盘、鼠标厂家按照USB接口的标准,去生产
电脑上有USB接口,U盘可以插入拷贝数据 鼠标插入可以用
USB只是对外提供一种服务,具体做什么不清楚,取决于外设什么,最终是外设在工作,对于USB本身来说,不工作,方法不好写,用抽象方法。
java中的接口就类似于USB,能有抽象方法 也有具体的方法 ,也是一种多态的应用
1 概念
是一种规范和标准,用来描述不同类事物的共同特征的方式
实际上,接口就是多态的应用,接口中的implements 等价于extends
2 特征
- 接口中的属性默认是public static final型(静态常量)
- 接口中的方法通常是public abstract型抽象方法
- 接口中可以有具体方法,但要添加default关键字(jdk 1.8以后支持)
- 接口中可以有静态方法(jdk1.8以后)
- 接口中支持多继承
- 接口中没有构造方法,不能产生对象
- 类在继承同时,可以实现多个接口
- 类与类之间:单继承
- 类和接口之间:实现 多个接口
- 接口与接口之间:多继承
3 接口和抽象类的区别
- 接口之间是多继承,抽象类是单继承
- 接口中属性是静态常量,而抽象类不需要
- 接口中没有构造方法,而抽象类有(但不能创建对象)
- 接口中的可以是抽象方法或default修饰的具体方法(jdk1.8新增),而抽象类中可以有任意类型的方法
4 面向接口编程
招聘一个程序员,会写代码、唱歌、打麻将等,只是关心这种能力,而不关心具体是哪个人
在java中,设计标准、能力,先定义接口而不关心具体的实现,这就是面向接口编程,是软件实现中一种设计风格,使得程序更具有兼容性。
软件公司,对于架构师而言,要架构一个系统,首先要确定功能、标准,而具体的实现由程序员完成,某种程度上体现了团队合作性。
5 jdk中的接口类型
- able型接口(以able结尾的),如Runnable Comparable
- 标准型接口(作为一种标准),如字符序列接口CharSequence
- 常量型接口(也常用具体的类表示,所有成员都是静态常量),如Constants类
- 标识型接口 (什么都没有) ,如 Cloneable、Serializable
6 接口应用
对数组的排序方法: 如Arrays.sort(数组名) 冒泡排序法 , 默认是升序
学生对象(姓名、年龄)数组排序步骤
-
定义一个学生类,实现Comparable接口
public class Student implements Comparable<Student>{ @Override public int compareTo(Student other) { // this当前对象和数组中其他对象比较 if (this.age>other.age) { return 1; //升序 }else if (this.age == other.age) { return 0; }else { return -1;//降序 } }
-
定义一个比较器类,实现Comparator接口
public class StudentComparator implements Comparator<Student>{ @Override public int compare(Student o1, Student o2) { if (o1.getAge() >o2.getAge()) { return 1; }else if (o1.getAge() == o2.getAge()) { return 0; }else { return -1; } } }
-
测试类
public static void main(String[] args) { StudentComparator sc = new StudentComparator(); Student[] s ={new Student("Tom",20),new Student("Marry",22),new Student("Jerry",18)}; //Arrays.sort(s); //出现类转换异常 Arrays.sort(s, sc); System.out.println(Arrays.toString(s)); }
7.13 内部类
1.普通内部类
public class Outer{
int a = 10;
// 1.普通内部类
class Inner{
int a1 =100;
void show(){
System.out.println("***普通内部类***");
System.out.println(this.a1);
System.out.println(Outer.this.a);
}
}
}
2.静态内部类
static class InStatic {
// 静态变量
static int s1 = 111;
int s2 = 222;
void m1() {
System.out.println("****静态内部类****");
System.out.println(s1);
}
}
3.局部内部类
void m(){
class Local{
int a = 100;
System.out.println("***局部内部类***");
System.out.println(a);
}
new Local();
}
4.匿名内部类***
public static void main(String[] args) {
final int a = 1000;
/**
* 1.定义一个类,该类没有名字
* 2.产生一个对象
*/
Person
person
=new Person() {
int num;
@Override
public void eat() {
num =100;
System.out.println(num);
System.out.println(a);
System.out.println("匿名内部类");
}
};
person.eat();
}
- 内部接口
Interface Inner{
void show();
}
7.14 枚举类
-
只能产生固定的对象,在定义时已经确定好了,作为属性存在
-
枚举的属性全是public static final型属性,类型和枚举的类型一致
//定义一个枚举类型
public enum Course {
Java,
MySql;
}
//
package day6.enumeration;
class Student{
String name;
Course c;
void show(){
System.out.println("姓名:"+name+",课程:"+c);
}
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.name = "张三";
stu.c =Course.Java;
stu.show();
switch (stu.c) {
case Java:
System.out.println("上java课程!");
break;
case MySql:
System.out.println("上mysql课程!");
break;
}
}
}
7.15克隆对象
步骤:
-
重写Object对象中clone()方法
-
实现Cloneable标识型接口
public class Monkey extends Object implements Cloneable{
String name;
int age;
public Monkey() {
System.out.println("无参构造");
}
public Monkey(String name, int age) {
super();
this.name = name;
this.age = age;
System.out.println("有参构造");
}
@Override
public String toString() {
return "Monkey [name=" + name + ", age=" + age + "]";
}
//克隆方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
//创建对象
Monkey m1 = new Monkey("金丝猴", 2);
Monkey m2 = (Monkey) m1.clone();
System.out.println(m1);
System.out.println(m2);
}
}
最后
以上就是怕黑小土豆为你收集整理的JAVA初学习(三)(数组和面向对象)六、数组七、面向对象的全部内容,希望文章能够帮你解决JAVA初学习(三)(数组和面向对象)六、数组七、面向对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复