目录
ArrayList list = new ArrayList<>(); //创建ArrayList集合
随机数添加入集合(.nextInt()获取随机数)选出来的r是整形数字
字符串获取 str.length() str1.concat(str2) str.chatAt(int index) str.indexOf(str2)
字符串的转换 str.toCharArray() str.getByhtes() str.replace(oldString,newString)
字符串的分割 String[] split(string regex)
static修饰的成员,方法都属于类,不能用对象来调用,必须用类名. 来调用
方法的覆盖重写(名称、参数一样)(返回值不要求)(方法重写只写构造方法以外的)
方法覆盖重写(在父类的基础上,对方法重写只写新增的,原有的方法体保留)
抽象方法(返回值前abstract,没有{},必须在抽象类中)(抽象类可以有一般方法)
2、抽象类的构造方法,只能通过具体子类的构造方法中的默认super()来调用
3、抽象类可以没有抽象方法,可以全空,但抽象方法必须在抽象类中
4、抽象类的子类,必须重写所有的抽象方法(如果不重写,会有空的继承的抽象方法被调用)
例:定义一个方法,传入参数为Animal的对象animal,
2、修饰方法,表示该方法不能被覆盖重写(最终方法)(final与abstract互斥)
public > protected > (default) > private
Eclipse 常用快捷键
* 进入方法的定义: ctrl + 该方法名
* alt + shift + r 统一重命名
* alt + shift + s 快捷键调出 get set 设置
* ”ctrl+H”打开文件搜索对话框
* alt+? 或 alt+/:自动补全代码或者提示代码
* ctrl+o:快速outline视图 查看当前类的方法或某个特定方法
成员变量和局部变量
成员变量(存在于堆内存中,和类一起创建)和局部变量(存在于栈内存中,当方法执行完成,让出内存,让其他方法来使用内存)
1、成员变量
类变量:从该类的准备阶段起开始存在,直到系统完全销毁这个类,类变量的作用域与这个类的生存范围相同;
实例变量:则从该类的实例被创建起开始存在,直到系统完全销毁这个实例,实例变量的作用域与对应实例的生存范围相同。
2、局部变量
形参:在定义方法签名时定义的变量,形参的作用域在整个方法中都有效
方法局部变量:在方法体内定义的局部变量,它的作用域是从定义该变量的地方生效,到该方法结束时失效
代码块局部变量:这个局部变量的作用域从定义该变量的地方生效,到该代码结束时失效。
https://blog.csdn.net/weixin_37012881/article/details/82699089
编程习惯
1、主函数主要写创建对象、
数组
动态数组初始化
int [] arrayA = new int [3];
静态初始化数组
int [] arrayA = new int[]{1,2,3};
或者
int [] arrayA ;
arrayA = new int []{1,2,3};
int [] arrayA ={1,2,3}; //不能被拆分
数组一旦创建,程序运行期间,长度不能改变
new 了两次,两个数组同时存在
地址值赋值给B
并没有在堆中给B新开空间,而是用的A的
输出数组的内容
Arrays.toString(int src);
数组索引越界异常:
数组索引编号写错
空指针异常:
NullPointerException 数组必须进行new初始化,才能使用其中元素
值进行赋NULL值,二没有new则会出错
方法的三种调用
1、打印调用 :System.out.println(方法名称(实际参数));
2、单独调用 :方法名称(实际参数);
3、赋值调用 :数据类型 变量名称 = 方法名称(实际参数);
方法重载
方法名相同,参数不同(类型不同,个数不同,不同类型顺序不同)
无法根据返回值类型不同重载
无法根据参数值不同重载
面向对象
普通的方法需要进栈
程序运行
1、方法区最先有数据(.class相关信息,各种类的信息(成员变量,成员方法))
2、main方法运行---先进栈,开辟一段内存空间
3、运行,就会在堆中创建一个Phone(),其中包括成员变量值,成员方法名(只是个地址)
4、给创建的实例化对象成员变量赋值,此时堆堆中的成员变量值就改变
5、调用成员方法,先方法进栈,然后调用方法执行,完成后释放出栈
6、程序完成后,main方法出栈
(new出来的都在堆当中)
栈:中存放的是局部变量,如Student one、main(string[] args)、sendMessage().
堆:中存放的是new出来的东西(对象的成员的值,及成员所有的方法)如new Student 、
方法区:放类的成员变量、成员方法,--------还有一个静态区---放静态成员变量
封装
alt + shift +s 中找到getset设置
关键字
protected
protected 对于子类来说,就变成public
被protected修饰的成员对于本包和其子类可见。
- 父类的protected成员是包内可见的,并且对子类可见;
- 若子类与父类不在同一包中,那么在子类中,子类实例可以访问其从父类继承而来的protected方法,而不能访问父类实例的protected方法
obj是父类实例,此时在子类所处的包p22中,在子类的方法中,通过创建父类实例访问父类protected方法不可行
而在子类中通过创建子类实例来访问继承来的父类protected 方法是可行的
private 保护数据安全
this
构造方法
自动生成全参构造方法
标准类POJO
基本布尔类型的Getter方法
布尔类型的成员变量的get方法,getxxx需要写成 isxxx
Scanner类
使用键盘输入都需要 导包 : import java.util.Scanner;
字符串也是对象
只要是字符串就是对象
直接写上一个双引号 “” 就是一个字符串对象
字符串常量也是一个字符串对象
字符串的两个问题
直接打印对象
结果
异常
捕获异常try ...catch
抛出异常 throw
声明异常 throws
成员方法抛出异常,不准确
解决方法:
1、在方法名后面添加 throws Exception,说明异常
2、在成员方法内,将throw写入try catch
推荐用第一种
写好抛出异常的方法后,当调用该方法时,还需要try catch 解决异常(直接点第二种,生成)
也可以用第一种,然后在main方法后面加throws Exception抛出异常给系统
匿名对象
没有左边的名字和赋值运算符,
每个匿名对象只能用一次,下次再用必须再次创建对象
此时有两个匿名对象,互不干扰
匿名对象做为参数
一般传参方法
匿名对象作为参数
随机数Random
1、导包
2、创建
Random r = new Random();
3、使用
int num = r.nextInt
int num = r.nextInt(int num);//范围在【0,num)
对象数组
用数组存储对象
缺点:一旦创建,运行期间长度不可以发生改变,当数组添加满时,需要重新创建对象数组。
Person [ ] array = new Person[3];
Person one = new Person(name:"古力娜扎",age:18);
Person two = new Person(name:"迪丽热巴",age:28);
Person three = new Person(name:"马尔扎哈",age:38);
array[0] = one;
array[1] = two;
array[2] = three;
System.out.println(array[0].getName());
System.out.println(array[1].getName());
System.out.println(array[2].getName());
ArrayList集合
数组长度不可以改变
ArrayList集合的长度可以改变。
ArrayList,有一个尖括号<E>,表示泛型。
泛型:装在集合中的所有元素,全都是统一的什么类型。
泛型只能是引用类型,不能是基本类型
要放基本类型,需要包装类
基本类型 包装类
byte Byte
short Short
int Integer 【特殊】
long Long
float Float
doulbe Doulbe
char Character 【特殊】
boolean Boolean
ArrayList<String> list = new ArrayList<>(); //创建ArrayList集合
System.out.println(list); //,打印的是内容,不是地址值,为空时打印结果为【】
集合方法
public boolean add(E e): 添加元素
public E get(int index): 获取元素
public E remove(int index): 删除元素
public int size(); 获取集合的长度
list.add("赵丽颖"); //两集合中添加元素
list.add("迪丽热巴");
list.add("古力娜扎");
System.out.println(list);//打印结果为 【赵丽颖,迪丽热巴,古力娜扎】
list.add(100); //出错,参数类型必须为创建时<>中的类型
随机数添加入集合(.nextInt()获取随机数)选出来的r是整形数字
要想修改集合的打印方式,要自定义一个打印方法,不能直接打印集合,需要一个一个遍历元素,然后自定义打印规则
用来存类的集合
定义一个学生类
创建一个学生类集合
1、创建学生对象
2、将学生对象添加到集合
3、循环打印集合
字符串的创建
对象就有方法(双引号租房穿就可以调用String的方法(equals方法等))
自动生成获取对象 Alt+Enter
(创建提取对象的方法时,Alt+Enter,自动生成变量)
字符串获取 str.length() str1.concat(str2) str.chatAt(int index) str.indexOf(str2)
length() concat() charAt() indeOf
length()
concat()
charAt()
indeOf()
字符串截取 str1.sbustring(n);
substring(int index)
substring(int begin,int end)
相当于C中指针指的地方不同,但是所创建的字符串没变
字符串的转换 str.toCharArray() str.getByhtes() str.replace(oldString,newString)
CharSquance:可以接受字符串类型。
字符串的分割 String[] split(string regex)
str1.split(regxe:",") //被分割后的字符串组(aaa bbb ccc),放入字符串数组array1。
静态static关键字
在类中,static定义的值,是类创建的所有对象的共有的。
static修饰的成员,方法都属于类,不能用对象来调用,必须用类名. 来调用
静态static关键字修饰成员
/*
如果一个成员变量使用了static关键字,那么这个变量不再属于对象自己,而是属于所在的类。多个对象共享同一份数据。
*/
//赋值时,调用的是学生类,而不是创建的学生对象
静态static修饰成员变量,可用作计数器
在有参构造方法中,idCounter是静态成员变量,当用有参构造创建对象时,id的值就会增加。
静态static关键字修饰成员方法
成员方法不是静态的,需要创建对象,通过对象来调用
成员方法如果是静态,直接通过类名来调用
this.表示当前对象。而static修饰的方法,所属为类。所以静态方法中不能拿用this。
静态代码块
小技巧:放在无参构造里的方法,在new对象时,肯定会执行
第二次时,静态代码块就不会运行
数组工具类Arrays
首先导包
toString()
sort()
技巧:chars.forr (倒序) chars.fori (正序)
数学相关的工具类Math
1、abs绝对值 2、ceil向上取整 3、floor向下去整 4、round四舍五入
继承
继承的格式
定义父类
定义一个子类,主函数中创建子类对象
定义一个新子类,主函数中创建新子类对象
继承中成员变量的访问特点
一、父类子类成员变量重名时
1、直接访问重名
先看创建对象等号“=”左边是谁,就用谁,子类创建的,就用子类的
2、间接用成员方法访问重名
就看方法属于谁的,就用谁
局部变量、本类成员变量、父类成员变量重名(成员方法中调用局部变量、本类成员变量、父类成员变量)
二、成员方法的调用,父类子类中的方法重名,看创建对象是谁,就用谁的的方法
注意事项
方法的覆盖重写(名称、参数一样)(返回值不要求)(方法重写只写构造方法以外的)
@override:写在方法前面,用来金阿册是不是方法的覆盖重写
当方法名,参数个数与父类不同时,会报错
子类方法返回值必须小于等于父类方法返回值范围
public >protected > (default) >private
方法覆盖重写(在父类的基础上,对方法重写只写新增的,原有的方法体保留)
继承中的构造方法访问
1、无参构造(父先子后)子类构造方法中有默认的 super()
用子类创建对象
先打印父类无参构造,后打印子类构造,通过super()访问父类重载构造。
2、父类有参构造,子类重写,用super(参数)。来调用
3、子类调用父类构造,不写送一个super(),写了用指定super,无参super()只能在子类构造方法中,且只有一个,必须在第一个。
super关键字用法
this用法
super和this在内存中图解
抽象方法(返回值前abstract,没有{},必须在抽象类中)(抽象类可以有一般方法)
抽象类和抽象方法的使用
子类方法重写的快捷方法
需要覆盖重写 alt + Enter ,选imlement menthods,然后选择需要重写的方法
然后改方法就会重写出来
注意事项:
1、抽象类不能创建对象(没有具体的方法)
2、抽象类的构造方法,只能通过具体子类的构造方法中的默认super()来调用
3、抽象类可以没有抽象方法,可以全空,但抽象方法必须在抽象类中
4、抽象类的子类,必须重写所有的抽象方法(如果不重写,会有空的继承的抽象方法被调用)
子类如果没有完全重写抽象类的全部抽象方法,也是一个抽象类,(因为抽象类所在的类你必须是抽象类)
爷爷类(抽象类)(两个抽象方法)
父类(抽象类)(还有一个抽象方法)
子类(普通类)(最后一个抽象方法也重写了)
发红包案例
以及构造方法和getter、setter
子类
//此时已经有父类的成员变量和成员方法,然后对继承的变量写有参无参构造(alt + insert)
//此时super(name,money), 是调用父类的构造方法,将传入Manager中的参数放入到父类构造中,进而放入父类成员变量
//成员的类
//主方法类
接口
----接口中放抽象方法、默认方法、私有方法
----实现类中放所有抽象方法的覆盖重写
----主方法类用实现类创建对象、用对象调用重写方法、接口中的默认方法
如何定义
注意事项
4、如果实现类没有覆盖重写接口的全部抽象方法,那么实现类就是一个抽象类
public abstract可以省略
修饰符和返回值类型可以省略
接口使用步骤
一般像实现哪个接口,就在接口名称后加上impl作为类名称
alt + enter 快速覆盖重写接口中的抽象方法
默认方法 (不需要在实现类中再次重写,就能用)
接口中的抽象方法都没有方法体,默认方法有方法体
拼接函数模型(南部大表达式)
注意事项:
接口升级:默认方法只需要定义在接口中,实现类创建对象后,就可以直接调用,不用再次在实现类中覆盖重写
多接口默认方法重名:必须在实现类中覆盖重写,且调用时,运行的是重写后的方法体
接口升级案例
接口中,最开始只有一个抽象方法,后来添加一个默认方法
两个接口实现类都只分别覆盖重写了第一个抽象方法
通过接口实现类A创建对/象 a ,调用实现方法和默认方法
注意事项:
实现类B中覆盖重写了默认方法,那么创建实现类B对象后,调用默认方法,就可以用B单独重写后的方法
通过接口,使用默认方法,可以对已经使用接口方法的类,进行升级,增加方法。
同时,实现类也可以对,新添加的默认方法覆盖重写。
接口中 静态方法(属于接口,通过接口名调用)
直接通过接口名,调用其中的静态方法
静态跟对象没关系,不需要创建对象来调用接口中的静态方法
私有方法(解决两个默认方法共享方法体)
接口中的常量(public static final)
shift + F6 变大写
总结接口内容
接口和类的同时使用
1、接口没有静态代码块
2、一个类只有一个父类,但可以有多个接口
只有一个父类和可以有多个接口(父类有方法,接口都是抽象方法不会造成多个接口方法的混乱)
-------- 接口改名 在左边项目框中选中,---------- shift + F6
错误写法
3、实现类重写多个接口中相同的抽象方法时,只需写一次
4、实现类重写多个接口中相同的默认方法,对象调用默认方法是,为重写的默认方法
5、父类中的方法和接口中默认方法产生冲突,优先用父类中的方法
接口可以同时继承多个接口
注意事项:
多态(Multi)(可以上下转型)
调用父类中定义的方法以及子类重写的方法(等号右边可调用的方法都是相同的方法名,不管是什么子类,特有方法不调用)
(多态创建的子类对象被当做父类使用)
(父类类型的引用指向子类对象)
多态成员变量的使用
1、直接调用
因为是父类类型的引用,所以创建出的对象调用调用父类中定义的成员变量
2、间接调用(类方法调用变量)
(调用子类方法中调用变量,就看方法属于谁)
多态调用成员方法
只能调用子类重写父类的方法,子类没有重写,就调用父类的成员方法
口诀:编译看左,运行看右
编译时,看左边Fu类,运行看右边 Zi(),里面有method();
编译时,看左边Fu类,运行看右边 Zi(),里面没有methodFu(),向上找父类有,运行通过
总结:
1、使用父类类型的引用指向子类对象,
2、该指向只能调用父类中定义的方法,如果子类重写了一个方法,则调用该子类方法(动态调用,动态链接)
对象的向上转型(一定是安全的)
父类 对象 = new 子类();(多态,子类转型成父类)
就是父类类型的引用指向子类对象,调用子类重写的方法
向上转型,不能再调用子类特有的方法
对象的向下转型
子类 对象 =(子类名称)父类对象
将父类对象还原成子类对象
对象向上向下转型
代码详情
向上转型为父类时,不能调用子类特有的方法
向下转型为子类,就可以调用子类的特有方法
上转时猫,下转时,不能直接变狗
Instanceof----向下转型时--判断
获取父类引用的对象,本来是什么子类
用途
例:定义一个方法,传入参数为Animal的对象animal,
【此时要判断,传进来的对象,就需要用intanceof判断,然后调用对应的方法】
final关键字
1、修饰类,表示没有子类(最终类)
并且,且的成员方法没有子类来重写
2、修饰方法,表示该方法不能被覆盖重写(最终方法)(final与abstract互斥)
3、修饰局部变量(做参数被调用时,不能被改变)
方法的参数也属于局部变
main()方法中的局部变量
// 对stu1重新用构造方法创建,地址值改变
// final修饰后,不能重新创建对象,地址值不能改变,但可以调用set()改变内容(地址值指向的对象内容可变)
// 此时是在main()方法中,final修饰局部变量stu1
4、修饰成员变量
// 直接赋值
那么尝试对该成员变量修改的方法都会错
// 通过构造赋值
通过默认构造赋值,当每个对象创建时,就被赋值,之后不能通过set()改变值
四种权限的修饰符
public > protected > (default) > private
同一个类中: private 修饰的都可以访问
同一个包中的不同类:没有修饰符,都可以访问。private 修饰的不能访问
不同包子类: 不写修饰符,不能访问
不同包: 只有public才能访问
内部类
成员内部类
内用外,随意访问;外用内,需要创建内部类对象
在文件夹中打开 重新编译 (外部类名$内部类名.class)
=》=》=》右键=》=》
成员内部类的使用
1、间接方式:外部方法创建内部对象,通过外部去调用内部
可以用匿名对象
2、直接方式:直接创建内部类对象【外部类名.内部类名 对象名 = new 外部类名(). new 内部类名();】
内部类变量同名访问
局部内部类
内部类在方法中
因为局部内部类在方法中,要在方法中创建对象,进行调用
类的权限修饰
外部类:public / (default)
成员内部类:所有
局部内部类:什么都不能写
局部内部类访问局部变量
局部内部类中访问,同在的方要法中的局部变量时,要求该变量不能改变(1、保持不改变其值;2、加上final修饰符)
因为内部类的存在比方法存在久,可能当方法消失了,内部类对象还存在,此时若要在调用方法中的局部变量,就要保证其不变
相当于滴啊用时,直接复制一次局部变量,之后就没局部变量什么关系了
匿名内部类
接口名 对象名 = new 接口名(){
//覆盖重写所有抽象方法
};
注意事项
【凡是要多次调用的,最好不用匿名内部类和匿名对象】
匿名内部类的匿名对象
但匿名对象调用方法只能用一次,要多次调用要多次创建匿名对象
类作为成员变量类型
https://blog.csdn.net/valentino112358/article/details/89048779
(需要创建对象,调用对象的成员变量)
使用时,创建对象,并用有参构造 对weapon对象赋值。
在用hero对象给它的成员变量weapon赋值,而赋值weapon就是一个对象
当weapon作为成员变量被调用时,要用它对象的成员变量
接口作为成员变量类型
直接调用,不用创建对象
// hero对象的set方法中传入匿名对象
由于hero的set方法参数为接口类型放入 new SkillImpl()会自动向上转型
即 等同于 Skill skill = new SkillImpl(); 创建对象
接口作为成员变量(调用接口实例化方法)
先创建实例化对象,即主类的成员变量,然后调用其方法
实例化方法
1、实例化接口 SkillImpl skillImpl = new SkillImpl(),并将实例化对象放入成员变量,然后调用接口抽象方法,
2、使用接口的匿名内部类 new Skill(){......};,重写所有抽象方法,相当于实例化对象
接口作为方法的参数
集合ArrayList也是类,List<String>是一种接口(但要导包.uill.List)
// 多态用法,ArrayList是接口List的实现类
接口类型做方法参数
重写toString()方法
sout(对象);就能直接输出对象的成员变量,不会输出地址值
快捷方式:alt + insert
匿名内部类和接口作为方法参数应用
接口:
主类:
主类方法
主类中调用 invokeCook 方法,匿名类内部接口实现类对象 为参数,调用了该匿名对象的makeFood方法