1. 参数传递
1.1 类名作为形参和返回值(应用)
-
1、类名作为方法的形参
方法的形参是类名,其实需要的是该类的对象
实际传递的是该对象的【地址值】
-
2、类名作为方法的返回值
方法的返回值是类名,其实返回的是该类的对象
实际传递的,也是该对象的【地址值】
-
示例代码:
class Cat { public void eat() { System.out.println("猫吃鱼"); } } class CatOperator { public void useCat(Cat c) { //Cat c = new Cat(); c.eat(); } public Cat getCat() { Cat c = new Cat(); return c; } } public class CatDemo { public static void main(String[] args) { //创建操作类对象,并调用方法 CatOperator co = new CatOperator(); Cat c = new Cat(); co.useCat(c); Cat c2 = co.getCat(); //new Cat() c2.eat(); } }
1.2 抽象类作为形参和返回值(理解)
-
抽象类作为形参和返回值
- 方法的形参是抽象类名,其实需要的是该抽象类的子类对象
- 方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
-
示例代码:
abstract class Animal { public abstract void eat(); } class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } } class AnimalOperator { public void useAnimal(Animal a) { //Animal a = new Cat(); a.eat(); } public Animal getAnimal() { Animal a = new Cat(); return a; } } public class AnimalDemo { public static void main(String[] args) { //创建操作类对象,并调用方法 AnimalOperator ao = new AnimalOperator(); Animal a = new Cat(); ao.useAnimal(a); Animal a2 = ao.getAnimal(); //new Cat() a2.eat(); } }
1.3 接口名作为形参和返回值(理解)
-
接口作为形参和返回值
- 方法的形参是接口名,其实需要的是该接口的实现类对象
- 方法的返回值是接口名,其实返回的是该接口的实现类对象
-
示例代码:
interface Jumpping { void jump(); } class JumppingOperator { public void useJumpping(Jumpping j) { //Jumpping j = new Cat(); j.jump(); } public Jumpping getJumpping() { Jumpping j = new Cat(); return j; } } class Cat implements Jumpping { @Override public void jump() { System.out.println("猫可以跳高了"); } } public class JumppingDemo { public static void main(String[] args) { //创建操作类对象,并调用方法 JumppingOperator jo = new JumppingOperator(); Jumpping j = new Cat(); jo.useJumpping(j); Jumpping j2 = jo.getJumpping(); //new Cat() j2.jump(); } }
2. 内部类
2.1 内部类的基本使用(理解)
-
内部类概念
- 在一个类中定义一个类。举例:在一个类A的内部定义一个类B,类B就被称为内部类
-
内部类定义格式
-
格式&举例:
/* 格式: class 外部类名{ 修饰符 class 内部类名{ } } */ class Outer { public class Inner { } }
-
-
内部类的访问特点
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
-
示例代码:
/* 内部类访问特点: 内部类可以直接访问外部类的成员,包括私有 外部类要访问内部类的成员,必须创建对象 */ public class Outer { private int num = 10; public class Inner { public void show() { System.out.println(num); } } public void method() { Inner i = new Inner(); i.show(); } }
2.2 成员内部类(理解)
-
成员内部类的定义位置
- 在类中方法,跟成员变量是一个位置
-
外界创建成员内部类格式
- 格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
- 举例:Outer.Inner oi = new Outer().new Inner();
-
成员内部类的推荐使用方案
- 将一个类,设计为内部类的目的,大多数都是不想让外界去访问,所以内部类的定义应该私有化,私有化之后,再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用。
-
示例代码:
class Outer { private int num = 10; private class Inner { public void show() { System.out.println(num); } } public void method() { Inner i = new Inner(); i.show(); } } public class InnerDemo { public static void main(String[] args) { //Outer.Inner oi = new Outer().new Inner(); //oi.show(); Outer o = new Outer(); o.method(); } }
2.3 局部内部类(理解)
-
局部内部类定义位置
- 局部内部类是在方法中定义的类
-
局部内部类方式方式
- 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
- 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
-
示例代码
class Outer { private int num = 10; public void method() { int num2 = 20; class Inner { public void show() { System.out.println(num); System.out.println(num2); } } Inner i = new Inner(); i.show(); } } public class OuterDemo { public static void main(String[] args) { Outer o = new Outer(); o.method(); } }
2.4 匿名内部类(应用)
-
匿名内部类的前提
- 存在一个类或者接口,这里的类可以是具体类也可以是抽象类
-
匿名内部类的格式
-
格式:new 类名 ( ) { 重写方法 } new 接口名 ( ) { 重写方法 }
-
举例:
new Inter(){ @Override public void method(){} }
-
-
匿名内部类的本质
- 本质:是一个继承了该类或者实现了该接口的子类匿名对象
-
匿名内部类的细节
-
匿名内部类可以通过多态的形式接受
Inter i = new Inter(){ @Override public void method(){ } }
-
-
匿名内部类直接调用方法
interface Inter{ void method(); } class Test{ public static void main(String[] args){ new Inter(){ @Override public void method(){ System.out.println("我是匿名内部类"); } }.method(); // 直接调用方法 } }
2.4 匿名内部类在开发中的使用(应用)
-
匿名内部类在开发中的使用
- 当发现某个方法需要,接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码
-
示例代码:
interface Jumpping { void jump(); } class Cat implements Jumpping { @Override public void jump() { System.out.println("猫可以跳高了"); } } class Dog implements Jumpping { @Override public void jump() { System.out.println("狗可以跳高了"); } } class JumppingOperator { public void method(Jumpping j) { //new Cat(); new Dog(); j.jump(); } } class JumppingDemo { public static void main(String[] args) { //需求:创建接口操作类的对象,调用method方法 JumppingOperator jo = new JumppingOperator(); Jumpping j = new Cat(); jo.method(j); Jumpping j2 = new Dog(); jo.method(j2); System.out.println("--------"); // 匿名内部类的简化 jo.method(new Jumpping() { @Override public void jump() { System.out.println("猫可以跳高了"); } }); // 匿名内部类的简化 jo.method(new Jumpping() { @Override public void jump() { System.out.println("狗可以跳高了"); } }); } }
3. 常用API
3.1 Math(应用)
-
1、Math类概述
- Math 包含执行基本数字运算的方法
-
2、Math中方法的调用方式
- Math类中无构造方法,但内部的方法都是静态的,则可以通过 类名.进行调用
-
3、Math类的常用方法
方法名 方法名 说明 public static int abs(int a) 返回参数的绝对值 public static double ceil(double a) 返回大于或等于参数的最小double值,等于一个整数 public static double floor(double a) 返回小于或等于参数的最大double值,等于一个整数 public static int round(float a) 按照四舍五入返回最接近参数的int public static int max(int a,int b) 返回两个int值中的较大值 public static int min(int a,int b) 返回两个int值中的较小值 public static double pow (double a,double b) 返回a的b次幂的值 public static double random() 返回值为double的正值,[0.0,1.0)
3.2 System(应用)
- System类的常用方法
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的 Java 虚拟机,非零表示异常终止 |
public static long currentTimeMillis() | 返回当前时间(以毫秒为单位) |
-
示例代码
- 需求:在控制台输出1-10000,计算这段代码执行了多少毫秒
public class SystemDemo { public static void main(String[] args) { // 获取开始的时间节点 long start = System.currentTimeMillis(); for (int i = 1; i <= 10000; i++) { System.out.println(i); } // 获取代码运行结束后的时间节点 long end = System.currentTimeMillis(); System.out.println("共耗时:" + (end - start) + "毫秒"); } }
3.3 Object类的toString方法(应用)
-
Object类概述
- Object 是类层次结构的根,每个类都可以将 Object 作为超类。所有类都直接或者间接的继承自该类,换句话说,该类所具备的方法,所有类都会有一份
-
查看方法源码的方式
- 选中方法,按下Ctrl + B
-
重写toString方法的方式
-
- Alt + Insert 选择toString
-
- 在类的空白区域,右键 -> Generate -> 选择toString
-
-
toString方法的作用:
- 以良好的格式,更方便的展示对象中的属性值
-
示例代码:
class Student extends Object { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } 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; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public class ObjectDemo { public static void main(String[] args) { Student s = new Student(); s.setName("林青霞"); s.setAge(30); System.out.println(s); System.out.println(s.toString()); } }
-
运行结果:
Student{name='林青霞', age=30} Student{name='林青霞', age=30}
3.4 Object类的equals方法(应用)
-
equals方法的作用
- 用于对象之间的比较,返回true和false的结果
- 举例:s1.equals(s2); s1和s2是两个对象
-
重写equals方法的场景
- 不希望比较对象的地址值,想要结合对象属性进行比较的时候。
-
重写equals方法的方式
-
- alt + insert 选择equals() and hashCode(),IntelliJ Default,一路next,finish即可
-
- 在类的空白区域,右键 -> Generate -> 选择equals() and hashCode(),后面的同上。
-
-
示例代码:
class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } 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; } @Override public boolean equals(Object o) { //this -- s1 //o -- s2 if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; //student -- s2 if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } } public class ObjectDemo { public static void main(String[] args) { Student s1 = new Student(); s1.setName("林青霞"); s1.setAge(30); Student s2 = new Student(); s2.setName("林青霞"); s2.setAge(30); //需求:比较两个对象的内容是否相同 System.out.println(s1.equals(s2)); } }
3.5 冒泡排序原理(理解)
- 冒泡排序概述
- 一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按要求完成排序
- 如果有n个数据进行排序,总共需要比较n-1次
- 每一次比较完毕,下一次的比较就会少一个数据参与
3.6 冒泡排序代码实现(理解)
- 代码实现
/*
冒泡排序:
一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,
依次对所有的数据进行操作,直至所有数据按要求完成排序
*/
public class ArrayDemo {
public static void main(String[] args) {
//定义一个数组
int[] arr = {24, 69, 80, 57, 13};
System.out.println("排序前:" + arrayToString(arr));
// 这里减1,是控制每轮比较的次数
for (int x = 0; x < arr.length - 1; x++) {
// -1是为了避免索引越界,-x是为了调高比较效率
for (int i = 0; i < arr.length - 1 - x; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
System.out.println("排序后:" + arrayToString(arr));
}
//把数组中的元素按照指定的规则组成一个字符串:[元素1, 元素2, ...]
public static String arrayToString(int[] arr) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
sb.append(arr[i]);
} else {
sb.append(arr[i]).append(", ");
}
}
sb.append("]");
String s = sb.toString();
return s;
}
}
3.7 Arrays(应用)
-
Arrays的常用方法
方法名 说明 public static String toString(int[] a) 返回指定数组的内容的字符串表示形式 public static void sort(int[] a) 按照数字顺序排列指定的数组 -
工具类设计思想
1、构造方法用 private 修饰
2、成员用 public static 修饰
引用类型作为方法形参和返回值
一、数据类型的回顾
1.基本数据类型
byte、short、int、long、float、double、char、boolean2.引用数据类型 类(API提供的、我们自定义的类)、数组、接口
二、方法的声明
修饰符 返回值 方法名(数据类型 变量名){ //这里所说的形参指的是 数据类型 xxxxxxxxxxxx }
三、类名作为形参和返回值 //(☆☆☆☆☆)
1.类名作为形参
*方法的形参是类名,其实需要的是 该类的对象、或者其子类的对象(多态)
实际传递的是该对象的【地址值】2.类名作为返回值 *方法的返回值是类名,其实返回的是 该类的对象、或者其子类的对象(多态) 实际传递的,也是该对象的【地址值】
四、抽象类名作为形参和返回值 //(☆☆☆☆☆)
1.抽象类名作为形参
*方法的形参是抽象类名,其实需要的是 其子类的对象(多态)2.抽象类名作为返回值 *方法的返回值是抽象类名,其实返回的是 其子类的对象(多态)
五、接口名作为方法的形参和返回值 //(☆☆☆☆☆)
1.接口名作为方法的形参
*方法的形参是接口名,其实需要的是 该接口的实现类对象、该接口的实现类的子类对象2.接口名作为方法的返回值 *方法的返回值是接口名,其实返回的是 该接口的实现类对象、该接口的实现类的子类对象
内部类
//重点掌握的是匿名内部类
//对于成员内部类和局部内部类 我们的要求是会创建对象调用方法就可以
一、内部类的概述
1.什么叫内部类?
类A的内部有一个类B,B就是一个内部类
2.特点 //了解
(1)内部类可以直接访问外部类的成员,包括私有
(2)外部类要访问内部类的成员,必须创建对象
二、内部类的分类
1.成员内部类
// 在类的成员位置定义的内部类
(1)举例:
public class Demo1 {
public int num =10;
public class Student implements English {
@Override
public void speak() {
System.out.println("学生学英语");
}
}
public static void main(String[] args) {
}
}
(2)怎么创建对象
外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
举例:
Demo1.Student ds = new Demo1().new Student();
ds.speak();
(3)请问外部类和内部类有没有继承关系?
没有
(4)面试题
public class Demo1 {
int num = 50;
public class Student implements English {
int num = 30;
@Override
public void speak() {
int num = 20;
System.out.println(num); //20
System.out.println(this.num); //30
// System.out.println(new Demo1().num); //50
System.out.println(Demo1.this.num); //50
}
}
}
2.局部内部类
//在类的局部位置定义的内部类
(1)举例:
public class Demo1 {
public static void main(String[] args) {
class Student implements English {
int num = 30;
@Override
public void speak() {
System.out.println("学生说英语");
}
}
}
}
(2)怎么创建对象
一定要在方法的内部 + 并且在局部内部类的下面
举例:
public class Demo1 {
public static void main(String[] args) {
class Student implements English {
int num = 30;
@Override
public void speak() {
System.out.println("学生说英语");
}
}
Student s1 = new Student(); // 在main方法的内部 + 在内部类Student的下面
s1.speak();
}
}
(3)面试题 //局部内部类访问局部变量,该局部变量必须是一个常量
public class Outer {
public void show(){
int num = 20; //这里局部变量其实是一个常量,之所以没加final是因为jdk版本的问题,jdk小于等于7的时候,必须加final,大于7的时候可以不加
class Inner{
public void method(){
System.out.println(num);
num = 30; //编译报错 当show放执行完之后,num是一个局部变量,在不使用的时候,会被垃圾回收期自动回收,
//而method方法是Inner i1= new Inner()来调用的,对象存在于堆内存,不会被
//垃圾回收期回收,所以这样就出问题。加上final之后,num就变成了常量,此时存在于方法区的常量池中,不会被释放
}
}
Inner i1 = new Inner();
i1.method();
}
}
3.匿名内部类
(1)发展过程
单个实现类 -------- 局部内部类 ------------ 匿名内部类
(2)格式
*new 类名 ( ) { 重写方法 } //类既可以是具体类,也可以是抽象类
*new 接口名 ( ) { 重写方法 }
举例: new Inter(){
@Override
public void method(){}
}
(3)匿名内部类的本质
本质:是一个继承了该类或者实现了该接口的子类匿名 "对象"
(4)匿名内部类的细节
匿名内部类可以通过多态的形式接受
Inter i = new Inter(){
@Override
public void method(){}
}
//什么时候需要将匿名内部类赋值给接口对象? 需要多次调用方法的时候
MyInter mi =new MyInter() { //因为匿名内部类对象我要使用多次
@Override
public void show() {
System.out.println("show");
}
};
mi.show(); //使用第一次
mi.show(); //使用第二次
mi.show(); //使用第三次
//什么时候不需要赋值给接口对象? 只使用一次
new MyInter() {
@Override
public void show() {
System.out.println("show");
}
}.show(); //只使用一次
常用的API(Application Programming Interface,应用程序接口)
一、Math类(和数学计算相关的类)
1.public static int abs(int a) 返回参数的绝对值
//左边:返回值为int类型 中:指的是一个绝对值 右边:参数是一个int类型的值
//举例: int a = Math.abs(-56); 56
2.public static double ceil(double a) 返回大于或等于参数的最小double值,等于一个整数 //天花板 //掌握
//左边:返回值为double类型 中:向上取整 右边:参数是一个double类型的值
//举例: double d1 = Math.ceil(12.16d) 13.0
3.public static double floor(double a) 返回小于或等于参数的最大double值,等于一个整数 //地板 //掌握
//左边:返回值为double类型 中:向下取整 右边:参数是一个double类型的值
//举例: double d2 = Math.floor(12.56d); 12.0
4.public static int round(float a) 按照四舍五入返回最接近参数的int //掌握
//左边:返回值为int类型 中:四舍五入 右边:参数是一个float类型的值
//举例: int a1 = Math.round(12.34f); 12
5.public static int max(int a,int b) 返回两个int值中的较大值
6.public static int min(int a,int b) 返回两个int值中的较小值
7.public static double pow(double a,double b) 返回a的b次幂的值
//左边:返回值为double类型 中:求a的b次方 右边:参数是两个double类型的数据
//double d3 = Math.pow(2.0,3.0); 8.0
//扩展:a^b : 异或 (相同为false,不同为true)
8.public static double random() 返回值为double的正值, //[0,1) 熟悉
//左边:返回值为double类型 中:求0-1之间的随机数 右边:参数为空
//举例:求[7,9]之间的随机数
*第一步:将这两个数同时减去一个数,使得第一个数为0
// [7,9] -7 [0,2]
*第二步:用第一步得到的末尾的数加上1
// 2+1 = 3
*第三步:使用random方法乘以第二步的值,再向下取整,最后加上第一步减去的值
// Math.random()*3 [0,3)
//(int)(Math.random()*3) [0,2]
// (int)(Math.random()*3)+7 [7,9]
二、System类(和系统相关的类)
1.static void exit(int status) 终止当前运行的Java虚拟机。 //了解
//左边:返回值为空 中:结束JVM 右边:参数为int类型的status
//status - 退出状态。 为0表示正常退出, 非0表示异常退出
//点击程序的右上角结束程序属于正常退出
2.static long currentTimeMillis() 返回当前时间(以毫秒为单位)。 //掌握
//左边:返回值为long 代表的是毫秒值 中:计算 "当前时间" 的毫秒值 右边:参数为空
//这个方法有一个默认的相对时间 1970-01-01 08:00:00 这个时间点是C语言诞生的日子,后来所有的语言都以这个时间为时间源点
//应用场景:
第一个:计算程序的执行时间
第二个:利用时间的唯一性 //举例:保证文件的不重名 a1002514.txt (☆☆☆☆☆)
三、Object类
1.String toString() 返回对象的字符串表示形式。
//左边:返回值为String 中:返回对象的字符串表示形式 右边:参数为空
//注意事项
(1)请问:Object类中的toString方法默认打印的是什么?
//地址值
(2)在API中,只有Object类中的toString方法返回的是"地址值" ,其他的类的toString方法都返回的是"属性值"
(3)到底什么时候需要使用属性值?
一般在我们"自定义"的类中,需要重写toString方法的
//要求:以后在写标准的JavaBean的时候,要加上toString方法
标准的JavaBean类的写法
*成员变量要使用private修饰
*提供对应的get和set方法
*提供空参构造
*提供全参构造
*提供toString方法
(4)怎么重写toString方法
使用idea自动生成
使用ALT + insert ------------- 选择toString()方法,自动生成即可
(5)Object 是类层次结构的根,每个类都可以将 Object 作为超类。所有类都直接或者间接的继承自该类,换句话说,该类所具备的方法,所有类都会有一份
//Object类是所有的类的直接或者间接根类
面试题:为什么子类构造方法默认访问的是父类的无参构造?
因为所有的类的直接或者间接根类都是object,而object类只有一个无参构造方法。
2. boolean equals(Object obj) 指示一些其他对象是否等于此。
//左边:返回值为boolean 中:比较对象是否相等 右边:参数为Object 可以是任意对象
//注意事项
(1)object类的equals方法比较的是什么?
"地址值"
(2)在API中,除了Object类,其他类的equals方法比较的还是地址值吗?
不是,比较的是"属性值"
(3)对于咱们自定义的类,如果我们想要比较属性值怎么办?
重写equals
(4)怎么重写equals方法?
idea自动生成
使用快捷键 ALT + insert ------------ equals()和hashCode() ,自动生成即可
(5)我们怎么知道一个类有没有重写过equals方法?
*Object:equals方法比较的,或者toString方法返回的都是"地址值"
*API中其他的类:equals方法比较的,或者toString方法返回的都是"属性值"
*自定义的类:如果我们重写了equals和toString方法,那么比较的是属性值;如果没有重写,比较的是地址值
冒泡排序://经常作为笔试题的最后一个题目 掌握
一、冒泡排序的原理
1.每一轮下来,咱们就会得到一个最大值
2.如果有n个数据参加比较,我们需要比较n-1轮
3.每一轮得到的最大值是不需要参与下一轮的比较的
二、代码实现
public class MaoPao {
public static void main(String[] args) {
int[] ints = {55,44,33,22,11};
for (int i = 0; i < ints.length-1; i++) { //外层循环其实就是你要循环多少轮 这里的-1是因为要比较的轮数是数据总个数-1
for (int j = 0; j < ints.length-i-1; j++) { //内层循环是用来比较每两个相邻元素之间的大小 这里的-i指的是已经确定了的最大值下一轮不需要进行比较
//-1是为了防止数组越界
if (ints[j]>ints[j+1]){
int temp = ints[j];
ints[j]=ints[j+1];
ints[j+1]=temp; //在交换位置的过程中,不会出现外层循环的i
}
}
}
//遍历排序后的数组
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
}
}
三、扩展
一个班级有50个学生,我要找出某一次考试成绩的前三名成绩?
//其实这里就是把外层循环的次数改为3就行了
Arrays类 (是一个操作数组的工具类)
1.static String toString(int[] a) 返回指定数组的内容的字符串表示形式。
//简单的说就是用来替代咱们钢带代码中的遍历的代码
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
------------------------------------------------------
System.out.println(Arrays.toString(ints));
2.static void sort(int[] a) 按照 "数字顺序"(从小到大的顺序) 排列指定的数组。
//其实这个方法是用来替代冒泡排序的
for (int i = 0; i < ints.length-1; i++) { //外层循环其实就是你要循环多少轮
for (int j = 0; j < ints.length-i-1; j++) { //内层循环是用来比较每两个相邻元素之间的大小
if (ints[j]>ints[j+1]){
int temp = ints[j];
ints[j]=ints[j+1];
ints[j+1]=temp;
}
}
}
--------------------------------------------------------------------------------------------
Arrays.sort(ints);
3.什么时候自己写冒泡排序算法?什么时候使用Arrays?
在实际开发中:Arrays.sort(ints);
在面试中:老老实实写冒泡算法
4.工具类
//以后在开发中,写工具类的要求
*工具类所在的包:必须以util或者utils结尾
*工具类名本身也必须以util或者utils结尾
*构造方法私有
*所有的方法必须使用static来修饰