1.数组
数组就是一种可以存储大量数据类型相同的变量的数据结构,数组就是具有相同数据类型的数据集合
数组基本要素
- 数组名称
- 数组元素
- 元素下标
- 数据类型
数组本身就是一个变量,数组名称就是变量名,数组中保存的每一个数据都会有一个下标(从0开始)
import java.lang.reflect.Array;
import java.util.Arrays;
public class Demo01 {
public static void main(String[] args) {
//声名数组
int[] array;
//分配内存空间
array = new int[6];
//给数组赋值
array[2] = 6;
String str = Arrays.toString(array);
System.out.println(str);
}
}
import java.util.Arrays;
public class Demo02 {
public static void main(String[] args) {
int [] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i+1;
}
System.out.println(Arrays.toString(array));
}
}
数组常见错误
- 数据类型不匹配
- 边声明边赋值的方法,代码必须卸载同一行,不能换行
- 数组下标越界
数组的常用操作及方法
- 求数组的最值
- 在数组的指定位置插入数据
- 对数组进行排序
求最值:
public class Demo03 {
public static void main(String[] args) {
int[] array = {23, 34, 45, 47, 78, 98};
int max = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i]>max){
max = array[i];
}
}
System.out.println("数组的最大值是:"+ max);
}
}
插入数据:
import java.util.Arrays;
public class Demo04 {
public static void main(String[] args) {
int[] array = {23, 34, 45, 47, 78, 98};
int num = 83;
int[] array2 = new int[array.length + 1];
System.out.println("插入前的结果为:"+ Arrays.toString(array));
for (int i = 0; i < 3; i++) {
array2[i] = array[i];
}
for (int i = 4; i < array2.length; i++) {
array2[i] = array[i-1];
}
array2[3] = num;
System.out.println("插入后的结果为:"+ Arrays.toString(array2));
}
}
排序:
import java.util.Arrays;
public class Demo05 {
public static void main(String[] args) {
int[] array = {98, 88, 76, 65, 54, 43};
for (int j = 0; j < array.length - 1; j++) {//对比array.length-1轮
for (int i = 0; i < array.length -1-j; i++) {//去掉已经比较的j轮
if (array[i]>array[i+1]){
int temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
}
}
}
System.out.println("排序后:"+ Arrays.toString(array));
}
}
binarySearch方法:寻找数组中的值,但是需要数组是有序数组。
2.二维数组
可以理解为一个一维数组中存着另一个一维数组。
import java.util.Arrays;
public class Demo06 {
public static void main(String[] args) {
int[][] array;// 声明
array = new int[2][3];//开辟内存空间
// int[] item = {20, 30 ,40};//赋值
// int[] item2 = {50, 60 ,70};
// array[0] = item;
// array[1] = item2;
int[][] array2= {{10,20,30},{12,23,23,34}};
String str = "";
for (int i = 0; i < array2.length; i++) {//第一维循环
// str +=Arrays.toString(array2[i]);
for (int j = 0; j < array2[i].length; j++) {
System.out.println(array2[i][j]);
}
}
// System.out.println(str);
}
}
public class Demo07 {
public static void main(String[] args) {
int[][] array = new int[3][6];
int sum = 0;
for (int i = 0; i < array.length; i++) {
System.out.println("-----------第"+(i+1)+"层货架-------------");
for (int j = 0; j < array[i].length; j++) {
int num =(i+1)*(j+1);
sum += num;
System.out.println("第"+(j+1)+"个格挡的鸡蛋个数为"+num);
}
}
System.out.println("鸡蛋的总数是"+sum);
}
}
3.综合练习
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTeBeQ86-1659669976574)(C:\Users\xwh666\AppData\Roaming\Typora\typora-user-images\image-20220729174927199.png)]
4.面向对象
面向对象编程思想:将程序模块化的思想。
类和对象
类和对象的关系
每个对象都有特定的特征:1、属性2、方法。
属性指的是对象的静态特征(车颜色,车牌),方法是描述动态特征(车跑动)。
对象是用来描述客观存在的一个实体,该实体是由一组属性和方法构成。
类是产生对象的模板,所有的对象都是通过类来创建的。
类是对象的抽象画描述,这些对象具有相同的特征和动作。
对象是类的具体实例。
java程序是以类为组织单元,程序运行时的主体是通过类创建的具体对象。
定义类
public class 类名{
//定义属性,属性符合驼峰命名法
public //数据类型 属性名
//定义方法,方法命名符合驼峰式命名法
public 返回值类型 方法名(参数列表:数据类型 参数名){
//方法体
}}
java中有返回值的方法需要在方法定义时指定返回值的数据类型,并在方法体中用return将结果返回给外部调用者。
如果一个方法不进行返回操作,那将返回值定义为void。
5.构造函数、构造方法、构造器
构造函数是一种特殊的方法,普通方法是用来描述某个动作,构造方法是用来创建对象的。
- 方法名必须与类名一致。
- 不需要定义返回值类型。
构造函数分为有参、无参构造
任何一个类都默认自带一个无参构造,如果手动在类中定义一个有参构造,则会覆盖默认的无参构造
6.this关键字
this 用来指代当前类的实例化对象,通过this可以调用当前类的属性和方法,比如在有参构造中,通过this将外部传入的值赋给当前类的实例化对象。
this除了可以在类中访问属性也可以在类中调用方法,类中的方法可以分为两类:构造方法、普通方法。
用this调用这两类方法的语法也不同,调用构造函数的语法是this(参数列表),不能在普通方法中使用this调用构造函数。
用this调用普通方法,this.方法名(参数列表),可以在构造函数中使用也可以在普通方法中使用。
7.成员变量和局部变量
变量的作用域:在程序中可以通过变量名来访问该变量的范围,变量的作用域由变量被声明时所在位置决定的,java中根据不同的作用域将变量分为成员变量和局部变量。直接看离它最近的包裹它的花括号 {}就是它的范围。
局部变量:在方法中声明。不会赋初始值,要设置否则会报错
成员变量:在方法外,类中声明。会赋初始值
8.封装
将类的属性隐藏在内部,外部不能直接访问和修改,如何实现?通过改变成员变量的可见性,从共有改为私有:属性私有,get/set
public class Student {
private int id;
private String name;
private int age;
public void show(){
System.out.println("学生信息如下:");
System.out.println("学生编号:"+id);
System.out.println("学生姓名:"+name);
System.out.println("学生年龄:"+age);
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age <= 0) {
System.out.println("输入的年龄有误!");
age = 3;
}
this.age = age;
}
}
public class Demo08 {
public void show(){
System.out.println();
}
public static void main(String[] args) {
Student student = new Student();
student.setId(1);
student.setName("张三");
student.setAge(-32);
student.show();
}
}
核心思想:
尽可能的把属性隐藏在内部,对外提供方法来访问,我们可以在这些方法中添加逻辑处理来实现过滤,以屏蔽错误数据的赋值。
步骤:
- 修改属性(成员变量)的访问权限为私有,使外部不能直接访问。
- 提供外部可以直接调用的方法
- 在该方法加入对于属性的逻辑控制,避免出现逻辑上的错误。
什么是访问权限?
访问权限指可以被直接访问的范围,是在属性定义时设定的,访问权限的可选项有4种:public、private、默认(不写)、protected,区别在于作用域范围不同。
9.static关键字
static表示静态或者全局变量,可以用来修饰成员变量和成员方法以及代码块。
使用static修饰的成员变量和成员方法独立于该类的任何一个实例化对象,访问时不依赖该类的对象,而是直接通过类去访问,可以理解为被该类的所有实例对象所共用,所以说是全局的。(本来要new一个对象,现在直接通过类调用就行了:student.xxx)
静态代码块的特点是只执行一次,什么时候执行?当这个类被加载到内存时执行,不需要开发者手动调用,会自动执行。
被加载到内存中的类叫做运行时类,静态代码块就是加载类时执行的,因为类只加载一次,所以静态代码块也只执行一次。
10.继承
描述类之间的关系,一个类继承(拥有)另一个类中的属性和方法,被继承的类叫做父类,继承的父类的类叫做子类
public class People {
private int id;
private String name;
private int age;
private char gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
}
public class Student extends People{
}
public class Teacher extends People{
}
java中继承是单继承,也就是一个子类只能有一个直接父类。
子类访问父类
创建一个子类对象时,会默认先创建一个父类对象。无论是通过有参或无参构造来创建对象,都是通过无参构造来创建父类对象的。
可以通过super关键字让子类创建对象时调用父类的有参构造
public Student(int id){
super(1);
System.out.println("通过有参构造创建了Student对象");
}
子类可以访问父类的构造方法、普通方法、成员变量,都是通过super关键字来完成,具体语法:
构造方法:super(参数列表)
普通方法:super.方法名(参数列表)
成员变量:super.成员变量名
普通方法:
public void show(){
super.setName("张三");
System.out.println(getName());
}
在子类的构造方法中,可以通过super访问父类的构造方法和普通方法。
在子类的普通方法中,只能通过super访问父类的普通方法。
子类的访问权限
访问权限修饰符:public、protected、默认修饰符、private
同一个类中 不同包 同一个包 子类(不同包)
public: 可以访问 可以访问 可以访问 可以访问
protected: 可以访问 不能访问 可以访问 可以访问
默认修饰符: 可以访问 不能访问 可以访问 不能访问
private: 可以访问 不能访问 不能访问 不能访问
包:package,用来管理java文件,为了防止产生冲突,可以把同名的java类分别放入不同的包中。
命名规范:由小写字母、数字组成不能以.和数字开头,使用.来分层。一般采用网络域名的反向输出,如com.conpany.test
11、方法重写
子类在继承的基础上,对父类方法重新定义并覆盖的操作。(继承的房子,重新装修)
规则
- 构造方法不能被重写
1、父子类方法名相同
2、父子类的方法参数列表相同
3、子类方法的返回值与父类方法返回值类型相同或者是其子类
4、子类方法的访问权限不能小于父类
12、方法重载
和方法重写的区别:
位置 | 方法名 | 参数列表 | 返回值 | 访问权限 | |
---|---|---|---|---|---|
重写 | 在子类中对父类方法重写 | 相同 | 相同 | 相同或是其子类 | 不能小于父类 |
重载 | 同一个类中 | 相同 | 不同 | 没有要求 | 没有要求 |
13、多态
一个事物具有多种表现形态,定义一个方法,在具体生成环境中根据不同需求呈现不同的业务逻辑,多态的前提是继承。
package com.southwind.test;
public class Member {
public void buyBook() {
}
}
package com.southwind.test;
public class SuperMember extends Member{
public void buyBook() {
System.out.println("超级会员买书打6折");
}
}
package com.southwind.test;
public class OrdinaryMember extends Member{
public void buyBook(){
System.out.println("普通会员买书打9折");
}
}
package com.southwind.test;
public class Cashier {
private Member member;
public Member getMember() {
return member;
}
public void setMember(Member member) {
this.member = member;
}
public void settlement(){
//this.ordinaryMember.buyBook();
this.member.buyBook();
}
}
package com.southwind.test;
public class Test {
public static void main(String[] args) {
OrdinaryMember ordinaryMember = new OrdinaryMember();
SuperMember superMember = new SuperMember();
Cashier cashier = new Cashier();
// cashier.setOrdinaryMember(ordinaryMember);
// cashier.setSuperMember(superMember);
cashier.setMember(superMember);
cashier.settlement();
}
}
多态具体表现形式:
1、定义方法时形参类型为父类,实际调用方法时传入子类类型的参数。
2、定义方法时返回类型为父类,实际调用方法时返回子类对象。
父类引用指向子类对象,子类superMember的实例化对象赋给父类引用
1、定义方法时形参类型为父类,实际调用方法时传入子类类型的参数:
public void settlement(Member member){//定义方法时形参类型为父类
//this.ordinaryMember.buyBook();
member.buyBook();
}
public static void main(String[] args) {
SuperMember superMember = new SuperMember();//实际调用方法时传入子类类型的参数
Cashier cashier = new Cashier();
cashier.settlement(superMember);
}
2、定义方法时返回类型为父类,实际调用方法时返回子类对象:
public Member getMember(String name){//定义方法时返回类型为父类
if (name.equals("super")){
return new SuperMember();//实际调用方法时返回子类对象
}else {
return new OrdinaryMember();
}
}
SuperMember superMember = new SuperMember();
Cashier cashier = new Cashier();
cashier.settlement(superMember);
14、抽象方法和抽象类
如果一个方法只有方法的声明而没有具体方法实现,这个方法就叫做抽象方法,需要用abstract关键字修饰
public abstract void buyBook();
一旦类中定义了抽象方法,则该类也必须声明为抽象类,需要在类定义处添加abstract关键字
public abstract class Member {
public abstract void buyBook();
}
抽象类与普通类的区别是抽象类不能被实例化,抽象方法与普通方法区别是抽象方法没有方法体。
抽象类中可以没有抽象方法,但是包含抽象方法的类必须定义为抽象类,即我们可以在抽象类中定义普通方法,但是在普通方法中不能定义抽象方法。
如果父类是抽象类,一旦子类继承了该抽象父类,则子类必须对父类的抽象方法进行重写,否则会报错。
package com.southwind.test;
public abstract class Member {
public abstract void buyBook();
}
@Override
public void buyBook() {
System.out.println("超级会员买书打6折");
}
如果子类也是抽象类,则可以不用重写父类的抽象方法。
15、Object类
是java官方提供的类,存放在java.lang包中,该类是所有类的直接或间接父类。
java中任何一个类都会继承Object中的public和protected方法。
Object类中经常被子类重写的方法:
- public String toString() 以字符串的形式返回对象的信息
- public boolean equals(Object obj) 判断两个对象是否相等
- public native int hashCode() 返回对象的散列码
16、包装类
是java提供的一组类,专门用来创建8种基本数据类型对应的对象**(将基本数据类型的数据封装成引用类型)**,一共有8个包装类,存放在java.lang包中,基本数据类型对应的包装类。通过构造函数new出来的就是引用对象,基本数据类型不能叫做对象,引用类型才叫对象
byte | Byte |
---|---|
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
包装类的体系结构
装箱和拆箱
是包装类的特有名词,装箱是指将基本数据类型转为相对应的包装类对象,拆箱就是将包装类对象转为对应的基本数据类型。
装箱
1、public Type(type value)
每个包装类都提供了一个有参构造函数:public Type(type value),用来实例化包装类对象。
public class Demo10 {
public static void main(String[] args) {
byte b = 1;
Byte byt = new Byte(b);
short s = 2;
Short shor = new Short(s);
int i = 3;
Integer integer = new Integer(i);
long l = 4;
Long lon = new Long(l);
float f = 5.5f;
Float flo = new Float(f);
double d = 6.6;
Double dou = new Double(d);
char cha = 'J';
Character charac = new Character(cha);
boolean bo = true;
Boolean bool = new Boolean(bo);
System.out.println(byt);
System.out.println(shor);
System.out.println(integer);
System.out.println(lon);
System.out.println(flo);
System.out.println(dou);
System.out.println(charac);
System.out.println(bool);
}
}
2、public Type(String value)/public Type(char value)
每个包装类还有一个重载构造函数,character类的重载构造函数:public Type(char value),其他包装类的重载构造函数:
public Type(String value).
Byte byt = new Byte("1");
Short shor = new Short("2");
Integer integer = new Integer("3");
Long lon =new Long("4");
Float flo = new Float("5.5f");
Double dou = new Double("6.6");
Character charac = new Character('J');
Boolean bool = new Boolean("true");
System.out.println(byt);
System.out.println(shor);
System.out.println(integer);
System.out.println(lon);
System.out.println(flo);
System.out.println(dou);
System.out.println(charac);
System.out.println(bool);
需要注意的是,Boolean类的构造函数中,当参数为"true"时,Boolean值为true,当参数不为”true“时,Boolean值为false。
3、valueOf(type value)静态方法,参数是基本数据类型的数据
每一个包装类都有一个valueOf(type value)方法
Byte b = 1;
Byte byt = Byte.valueOf(b);
Short s = 2;
Short shor = Short.valueOf(s);
System.out.println(byt);
System.out.println(shor);
4、valueOf(String value)/valueOf(char b=value)专门为Character转换使用的其他的7个包装类都可以使用valueOf(String value)
Byte byt = Byte.valueOf("1");
Short shor = Short.valueOf("2");
System.out.println(byt);
System.out.println(shor);
需要注意的是,Boolean.valueOf(String value)方法中,当value为"true"时,Boolean值为true,否则,Boolean值为false。
拆箱
1、*Value()
每个包装类都有一个*Value()方法,通过该方法可以将包装类转为基本数据类型。 星号 指的是基本数据类型
Byte byt = Byte.valueOf("1");
Short shor = Short.valueOf("2");
byte b = byt.byteValue();
short sh = shor.byteValue();
2、parse*(String value)
除了character类以外每一个包装类都有一个静态方法可以将字符串类型转为基本数据类型。
byte b = Byte.parseByte("1");
short sh = Short.parseShort("2");
System.out.println(b);
System.out.println(sh);
3、toString(type value)
每个包装类都有该方法,作用是将基本数据类型转为String类型。
byte b = 1;
String bstr = Byte.toString(b);
short sh = 2;
String shstr = Short.toString(sh);
System.out.println(b);
System.out.println(sh);