本笔记是个人笔记+摘录笔记相结合,非完全原创
day01
cls : (clear screen)清屏
/*
需求:求两个数的和
*/
class FunctionDemo4
{
public static void main(String[] args)
{
//jvm会根据不同的参数去调用不同的功能
System.out.println(sum(10,20));
System.out.println(sum(10,20,30));
System.out.println(sum(10,20,30,40));
System.out.println(sum(10.5f,20));
}
//需求1:求两个数的和
public static int sum(int a, int b)
{
System.out.println("int");
return a + b;
}
//需求2:求三个数的和
public static int sum(int a, int b, int c)
{
return a + b + c;
}
//需求3:求四个数的和
public static int sum(int a, int b, int c, int d)
{
return a + b + c + d;
}
public static float sum(float a,float b)
{
System.out.println("float");
return a + b + c + d;
}
}
public static void reverse(int[] arr) {
for(int x=0; x
public static void reverse(int[] arr) {
for(int start=0,end=arr.length-1; start<=end; start++,end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
public static int getIndex(int[] arr,int value) {
for(int x=0; x
public static int getIndex(int[] arr,int value) {
int index = -1;
for(int x=0; x
day06
1.二维数组
就是元素为一维数组的一个数组。
格式1
数据类型[][] 变量名 = new 数据类型[m][n];
m表示这个二维数组有多少个一维数组
n表示每一个一维数组的元素个数
举例:
int[][] arr = new int[3][2];
定义了一个二维数组arr
这个二维数组有3个一维数组,名称是arr[0],arr[1],arr[2]
每个一维数组有2个元素,可以通过arr[m][n]来获取
表示获取第m+1个一维数组的第n+1个元素
注意:
A:以下格式也可以表示二维数组
a:数据类型 数组名[][] = new 数据类型[m][n];
b:数据类型[] 数组名[] = new 数据类型[m][n];
一个实例
public static void main(String[] args) {
//定义一个二维数组
int[][] arr = new int[3][2];
//定义了一个二维数组arr
//这个二维数组有3个一维数组的元素
//每一个一维数组有2个元素
//输出二维数组名称
System.out.println(arr); //地址值 [[I@175078b
//输出二维数组的第一个元素一维数组的名称
System.out.println(arr[0]); //地址值 [I@42552c
System.out.println(arr[1]); //地址值 [I@e5bbd6
System.out.println(arr[2]); //地址值 [I@8ee016
//输出二维数组的元素
System.out.println(arr[0][0]); //0
System.out.println(arr[0][1]); //0
}
二维数组格式1的内存图解
格式2
数据类型[][] 数组名 = new 数据类型[m][];
m:表示这个二维数组有多少个一维数组。
列数没有给出,可以动态的给。这一次是一个变化的列数。
举例
public static void main(String[] args) {
//定义数组
int[][] arr = new int[3][];
System.out.println(arr); //[[I@175078b
System.out.println(arr[0]); //null
System.out.println(arr[1]); //null
System.out.println(arr[2]); //null
//动态的为每一个一维数组分配空间
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
System.out.println(arr[0]); //[I@42552c
System.out.println(arr[1]); //[I@e5bbd6
System.out.println(arr[2]); //[I@8ee016
System.out.println(arr[0][0]); //0
System.out.println(arr[0][1]); //0
//ArrayIndexOutOfBoundsException
//System.out.println(arr[0][2]); //错误
arr[1][0] = 100;
arr[1][2] = 200;
}
格式1,格式2属于动态初始化
格式3
基本格式:
数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};
简化版格式:
数据类型[][] 数组名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};
举例:
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
int[][] arr = {{1,2,3},{4,5},{6}};
举例
public static void main(String[] args) {
//定义数组
int[][] arr = {{1,2,3},{4,5},{6}};
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[0][0]); //1
System.out.println(arr[1][0]); //4
System.out.println(arr[2][0]); //6
System.out.println(arr[0][1]); //2
System.out.println(arr[1][1]); //5
//越界
System.out.println(arr[2][1]); //错误
}
2.二维数组的遍历
外循环控制的是二维数组的长度,其实就是一维数组的个数。
内循环控制的是一维数组的长度。
代码如下
public static void main(String[] args) {
//定义一个二维数组
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
//arr[0]就是第一个数组
//arr[0] = {1,2,3};
for(int x=0; x
System.out.println(arr[0][x]);
}
System.out.println("--------------");
for(int x=0; x
System.out.println(arr[1][x]);
}
System.out.println("--------------");
for(int x=0; x
System.out.println(arr[2][x]);
}
System.out.println("--------------");
//用循环改进
for(int x=0; x<3; x++) {
for(int y=0; y
System.out.print(arr[x][y]+" ");
}
System.out.println();
}
System.out.println("--------------");
//3是我们根据上面的代码得出来的
//但是,它不能针对任何的数组都可以这样
//其实外面的这个循环的长度就是二维数组的长度
for(int x=0; x<arr.length; x++) {
for(int y=0; y<arr[x].length; y++) {
System.out.print(arr[x][y]+" ");
}
System.out.println();
}
System.out.println("--------------");
//用方法改进
//调用方法
printArray2(arr);
System.out.println("--------------");
//我们再来一个列数是变化的
int[][] arr2 = {{1,2,3},{4,5},{6}};
printArray2(arr2);
}
/*
需求:遍历二维数组
两个明确:
返回值类型:void
参数列表:int[][] arr
*/
public static void printArray2(int[][] arr) {
for(int x=0; x
for(int y=0; y
System.out.print(arr[x][y]+" ");
}
System.out.println();
}
}
3.二维数组累加求和
核心代码
//通过遍历就可以得到每一个二维数组的元素。
for(int x=0; x
{
for(int y=0; y
{
//把元素累加即可。
sum += arr[x][y];
}
}
4.Java参数传递问题
Java中的参数传递问题:
基本类型:形式参数的改变对实际参数没有影响。
引用类型:形式参数的改变直接影响实际参数。
例子
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a:"+a+",b:"+b); //a:10,b:20
change(a,b);
System.out.println("a:"+a+",b:"+b); //??? a:10,b:20
int[] arr = {1,2,3,4,5};
change(arr);
System.out.println(arr[1]); //??? 4
}
public static void change(int a,int b) { //a=10,b=20
System.out.println("a:"+a+",b:"+b); //a:10,b:20
a = b; //a=20
b = a + b; //b=40
System.out.println("a:"+a+",b:"+b); //a:20,b:40
}
public static void change(int[] arr) { //arr={1,2,3,4,5};
for(int x=0; x
if(arr[x]%2==0) {
arr[x]*=2;
}
}
//arr={1,4,3,8,5};
}
一句话:在Java中,只有值传递,只不过基本类型传递的是基本类型的数据值,而引用类型传递的是地址值
6.面向对象思想
面向对象是基于面向过程的编程思想。
面向过程:强调的是每一个功能的步骤
面向对象:强调的是对象,然后由对象去调用功能
2:面向对象的思想特点
A:是一种更符合我们思想习惯的思想
B:可以将复杂的事情简单化
C:将我们从执行者变成了指挥者
举例:
买电脑:
面向过程:我的了解电脑--了解我自己的需求--找对应的参数信息--去中关村买电脑--讨价还价--买回电脑
面向对象:我知道我要买电脑 -- 班长去给我买 -- 班长就买回来了
洗衣服:
面向过程:把衣服脱下--找一个盆--放点洗衣粉--加点水--把衣服扔进去--搓一搓--清洗衣服--拧干--晾起来
面向对象:把衣服脱下--打开全自动洗衣机--扔进去--一键即可--晾起来
吃饭:
面向过程:去超市买菜--摘菜--洗菜--切菜--炒菜--盛起来--吃
面向对象:上饭店吃饭,你--服务员(点菜)--厨师(做菜)--服务员(端菜)--吃
3.开发,设计,特征
面向对象开发
就是不断的创建对象,使用对象,指挥对象做事情。
面向对象设计
其实就是在管理和维护对象之间的关系。
面向对象特征
封装(encapsulation)
继承(inheritance)
多态(polymorphism)
4.面向过程与面向对象
举例:把大象装进冰箱
面向过程:
动作有哪些呢?
A:打开冰箱门
B:装进大象
C:关闭冰箱门
面向对象:
我们怎么才能更符合面向对象思想呢?
A:有哪些类呢?
B:每个类有哪些东西呢?
C:类与类直接的关系是什么呢?
把大象装进冰箱的分析? (如何分析有哪些类呢?UML。名词提取法。)
A:有哪些类呢?
大象
冰箱
Demo
B:每个类有哪些东西呢?
大象:
进去
冰箱:
开门
关门
Demo:
main方法
C:类与类直接的关系是什么呢?
Demo中使用大象和冰箱类的功能。
5.现实世界中是如何描述一个事物的呢?
举例:学生
姓名,年龄,性别...
学习,吃饭,睡觉
属性:该事物的描述信息
行为:该事物能够做什么
我们学习编程语言,是为了模拟现实世界的事物的。
而我们学习的编程语言Java中最基本的单位是:类。
所以,我们就应该把事物通过类来体现出来:
由此,我们就得到了现实世界事物和类的对应关系:
事物: 类:
属性 成员变量
行为 成员方法
类:是一组相关的属性和行为的集合。是一个抽象的概念。
对象:是该类事物的具体表现形式。具体存在的个体。
举例:
学生:类
班长:对象
=================================
现实世界的事物
事物:
属性 人的身高,体重等
行为 人可以学习,吃饭等
Java中用class描述事物也是如此
类:
成员变量 就是事物的属性
成员方法 就是事物的行为
定义类其实就是定义类的成员(成员变量和成员方法)
===========================================================
6.
在一个java文件中写两个类:一个基本的类,一个测试类。
注意:文件名称和测试类名称一致。
如何使用呢?
创建对象使用。
如何创建对象呢?
格式:类名 对象名 = new 类名();
如何使用成员变量呢?
对象名.变量名
如何使用成员方法呢?
对象名.方法名(...)
7……
一个对象的内存图
二个对象的内存图
三个对象的内存图
使用类的内容
a:创建对象? 格式
类名 对象名 = new 类名();
b:如何使用成员变量和成员方法呢
对象名.成员变量
对象名.成员方法()
day07
1.成员变量和局部变量
一个实例
class Varialbe {
//成员变量
//int num = 10;
int num; //0
public void show() {
//int num2 = 20; //局部变量
//可能尚未初始化变量num2
//int num2; //没有默认值
int num2 = 20;
System.out.println(num2);
//int num = 100;
System.out.println(num);
}
}
class VariableDemo {
public static void main(String[] args) {
Varialbe v = new Varialbe();
System.out.println(v.num); //访问成员变量
v.show();
}
}
成员变量和局部变量的区别?
A:在类中的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
成员变量:在堆内存
局部变量:在栈内存
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
注意事项:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
例如,上面关于num的输出问题
2.
形式参数的问题:
基本类型:形式参数的改变不影响实际参数(值传递)
引用类型:形式参数的改变直接影响实际参数(引用传递)
===============================================================================
//形式参数是引用类型
class Student {
public void show() {
System.out.println("我爱学习");
}
}
class StudentDemo {
//如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
public void method(Student s) {
//调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
s.show();
}
}
class ArgsTest {
public static void main(String[] args) {
//形式参数是引用类型的调用
//需求:我要调用StudentDemo类中的method()方法
StudentDemo sd = new StudentDemo();
//创建学生对象
Student s = new Student();
sd.method(s); //把s的地址给到了这里
}
}
===============================================================================
3.匿名对象
匿名对象:就是没有名字的对象。
匿名对象的应用场景:
A:调用方法,仅仅只调用一次的时候。
注意:调用多次的时候,不适合。
那么,这种匿名调用有什么好处吗?
有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
B:匿名对象可以作为实际参数传递
class Student {
public void show() {
System.out.println("我爱学习");
}
}
class StudentDemo {
public void method(Student s) {
s.show();
}
}
class NoNameDemo {
public static void main(String[] args) {
//带名字的调用
Student s = new Student();//虽然也在堆内存里,但是有s地址连接着new Student(),new Student()不会这么快消失(只要s还存在)
s.show();
s.show();//同一个对象被调用两次
System.out.println("--------------");
//匿名对象
//new Student();
//匿名对象调用方法
new Student().show();
new Student().show(); //这里其实是重新创建了一个新的对象。因为这是在堆内存的,调用完就消失了
System.out.println("--------------");
匿名对象可以作为实际参数传递
//匿名对象作为实际参数传递
StudentDemo sd = new StudentDemo();
//Student ss = new Student();
//sd.method(ss); //这里的s是一个实际参数
//匿名对象
sd.method(new Student());
//在来一个
new StudentDemo().method(new Student());
4.
private:私有的。可以修饰成员变量和成员方法。
注意:被private修饰的成员只能在本类中访问。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
例子
class Student {
String name;
private int age;
//写一个方法对数据进行校验
public void setAge(int a) {
if(a < 0 || age > 120) {
System.out.println("你给的年龄有问题");
}else {
age = a;
}
}
//show()方法,显示所有成员变量值
public void show() {
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
}
}
class StudentDemo {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
s.show();
System.out.println("--------------");
//给成员变量赋值
s.name = "林青霞";
//s.age = 27;
s.setAge(27);
s.show();
System.out.println("--------------");
//给age赋值
//s.age = -27; //这个数据是不合理的,加上private后age只能在Student类中使用而不能在StudentDemo中使用
//通过方法给值
s.setAge(-27);
s.show();
System.out.println("--------------");
}
}
5.封装和private的应用:
A:把成员变量用private修饰
B:提高对应的getXxx()和setXxx()方法
class Student
{
private String name;
private int age;
public String getName()
{
return name;
}
public void setName(String n)
{
name = n;
}
public int getAge()
{
return age;
}
public void setAge(int a)
{
age = a;
}
}
//测试类
class StudentTest {
public static void main(String[] args)
{
//创建学生对象
Student s = new Student();
//使用成员变量
//错误:被私有修饰了,外界不能直接访问了
//System.out.println(s.name+"---"+s.age);
System.out.println(s.getName()+"---"+s.getAge());
//给成员变量赋值
//s.name = "林青霞";
//s.age = 27;
//通过方法给赋值
s.setName("林青霞");
s.setAge(27);
System.out.println(s.getName()+"---"+s.getAge());
}
}
6.this关键字
this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。
注意:谁调用这个方法,在该方法内部的this就代表谁。
this的场景:
解决局部变量隐藏成员变量
例子
===================================================================
class Student {
private String name;
public String getName() {
return name;
/*public void setName(String n)
{
name = n;//不用this关键字的以前用法,但是s的名字不够鲜明于是改为name
}*/
public void setName(String name) { //name = "林青霞";
//name = name; //变量的使用规则:就近原则
//这里是类名,目前还没有说过类似的用法,所以这个是有问题的
//这里的调用只能通过对象名
//这个对象如果存在,它应该代表的是Student的一个对象。
//那么,谁能够代表当前类的对象呢? java就提供了一个关键字 this
//Student.name = name;
this.name = name;
}
}
class StudentTest {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
//给成员变量赋值
s.setName("林青霞");
System.out.println(s.getName());
}
}
==================================================================================
this:哪个对象调用那个方法,this就代表那个对象
this关键字的内存图解.bmp
7.构造方法
构造方法:
给对象的数据进行初始化
格式:
A:方法名与类名相同
B:没有返回值类型,连void都没有
C:没有具体的返回值
例子
class Student {
public Student() {
System.out.println("这是构造方法");
}
}
class ConstructDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
System.out.println(s); //Student@e5bbd6
}
}
构造方法的注意事项:
A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
例子:
class Student
{
}
class ConstructDemo2
{
public static void main(String[] args)
{
//创建对象
Student s = new Student();
}
}
反编译后
通过反编译可知
主要是new Student()引发的构造方法Student(反编译中的图解)public 为默认所以上图不显示
B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。(构造方法也可以重载,即带不同参数--默认不带参数)
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
8.
类的组成:成员变量,成员方法
今天我们又加入了一个新的成员:构造方法。
以后再提类的组成:
成员变量
构造方法
成员方法
图解
9.注意:
import必须出现在所有的class前面。
例如
1 import java.util.Scanner; 2 class …… 3 { 4 5 } 6 class …… 7 { 8 9 }
10.static
static的特点:(它可以修饰成员变量,还可以修饰成员方法)
A:随着类的加载而加载
回想main方法。
B:优先于对象存在
C:被类的所有对象共享
举例:咱们班级的学生应该共用同一个班级编号。
其实这个特点也是在告诉我们什么时候使用静态?
如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
举例:
饮水机(用静态修饰)(饮水机可以多人共享使用)
水杯(不能用静态修饰)(水杯只能自己一个人用,原则上不可以共享,每个人都有一个)
D:可以通过类名调用
其实它本身也可以通过对象名调用。
推荐使用类名调用。
静态修饰的内容一般我们称其为:与类相关的,类成员
静态变量也可以通过类名调用.png
11.static关键字注意事项
A:在静态方法中是没有this关键字的
如何理解呢?
静态是随着类的加载而加载,this是随着对象的创建而存在。
静态比对象先存在。
B:静态方法只能访问静态的成员变量和静态的成员方法
静态方法:
成员变量:只能访问静态变量
成员方法:只能访问静态成员方法
非静态方法:
成员变量:可以是静态的,也可以是非静态的
成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
简单记:
静态只能访问静态。(非静态可以访问一切)
例子
1 class Teacher { 2 public int num = 10; 3 public static int num2 = 20; 4 5 public void show() { 6 System.out.println(num); //语句1,隐含的告诉你访问的是成员变量 7 System.out.println(this.num); //语句2,明确的告诉你访问的是成员变量,与语句1相同效果 8 System.out.println(num2); 9 10 //function(); 11 //function2(); 12 } 13 14 public static void method() { 15 //无法从静态上下文中引用非静态 变量 num 16 //System.out.println(num); 17 System.out.println(num2); 18 19 //无法从静态上下文中引用非静态 方法 function() 20 //function(); 21 function2(); 22 } 23 24 public void function() { 25 26 } 27 28 public static void function2() { 29 30 } 31 } 32 33 class TeacherDemo { 34 public static void main(String[] args) { 35 //创建对象 36 Teacher t = new Teacher(); 37 t.show(); 38 System.out.println("------------"); 39 t.method(); 40 } 41 }
12.静态变量和成员变量的区别
所属不同
静态变量属于类,所以也称为为类变量
成员变量属于对象,所以也称为实例变量(对象变量)
内存中位置不同
静态变量存储于方法区的静态区
成员变量存储于堆内存
内存出现时间不同
静态变量随着类的加载而加载,随着类的消失而消失
成员变量随着对象的创建而存在,随着对象的消失而消失
调用不同
静态变量可以通过类名调用,也可以通过对象调用
成员变量只能通过对象名调用
13.
main方法的格式讲解:
public static void main(String[] args) {...}
public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
main:是一个常见的方法入口。我见过的语言都是以main作为入口。
String[] args:这是一个字符串数组。值去哪里了?
这个东西到底有什么用啊?怎么给值啊?
这个东西早期是为了接收键盘录入的数据的。
格式是:
java MainDemo hello world java
例子
1 class MainDemo { 2 public static void main(String[] args) { 3 //System.out.println(args); //[Ljava.lang.String;@175078b 4 //System.out.println(args.length); //0 5 //System.out.println(args[0]); //ArrayIndexOutOfBoundsException 6 7 //接收数据后 8 System.out.println(args); 9 System.out.println(args.length); 10 //System.out.println(args[0]); 11 for(int x=0; x) { 12 System.out.println(args[x]); 13 } 14 } 15 }
补充:
private是封装的一种表现。
思考题:构造方法中可不可以有return语句呢?
可以。而是写成这个样子:return;
day08
1.首先要注意,在同一个文件夹下,类定义在两个文件中和定义在一个文件中其实一样的。
2.例子
===========================================================================
class ArrayTool {
//把构造方法私有,外界就不能在创建对象了
private ArrayTool(){}
public static void printArray(int[] arr) {
for(int x=0; x
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
}
=====================================================
class ArrayDemo {
public static void main(String[] args) {
//定义数组
int[] arr = {28,55,37,46,19};
//需求:遍历数组
/*
for(int x=0; x
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
*/
//如果我有多个数组都要进行遍历,那么,代码的重复度就很高
//如何改进呢?用方法改进
//调用
//静态方法
//printArray(arr);
//非静态方法
//ArrayDemo ad = new ArrayDemo();
//ad.printArray(arr);
//测试类的作用:创建其他类的对象,调用其他类的功能。
//而我们现在的操作是跟数组相关的,所以,你应该把这些操作定义到数组操作类中
//定义一个数组的操作类
//有了数组操作类之后的调用
//ArrayTool at = new ArrayTool();
//at.printArray(arr);
//方法改进为静态后,就可以直接通过类名调用
ArrayTool.printArray(arr);
}
/*
public static void printArray(int[] arr) {
for(int x=0; x
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
*/
//假设该方法不是静态的
/*
public void printArray(int[] arr) {
for(int x=0; x
if(x == arr.length-1) {
System.out.println(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
}
*/
}
=======================================================================
3.制作文档注释,文档说明书
注意:如何制作一个说明书呢?
A:写一个工具类
B:对这个类加入文档注释
怎么加呢?
加些什么东西呢?
C:用工具解析文档注释
javadoc工具
D:格式
javadoc -d 目录 -author -version ArrayTool.java
目录:就可以写一个文件夹的路径
制作帮助文档出错:
找不到可以文档化的公共或受保护的类:告诉我们类的权限不够(解决办法:在class前面加public)
实例
=================================================================================
/**
* 这是针对数组进行操作的工具类
* @author 刘意
* @version V.10
*/
public class ArrayTool {
//把构造方法私有,外界就不能在创建对象了
/**
* 这是私有构造
*/
private ArrayTool(){}
/**
* 这是遍历数组的方法,遍历后的格式是:[元素1, 元素2, 元素3, ...]
* @param arr 这是要被遍历的数组
*/
public static void printArray(int[] arr) {
System.out.print("[");
for(int x=0; x
if(x == arr.length-1) {
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+", ");
}
}
}
/**
* 这是获取数组中最大值的方法
* @param arr 这是要获取最大值的数组
* @return 返回数组中的最大值
*/
public static int getMax(int[] arr) {
int max = arr[0];
for(int x=1; x
if(arr[x] > max) {
max = arr[x];
}
}
return max;
}
/**
* 获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1
* @param arr 被查找的数组
* @param value 要查找的元素
* @return 返回元素在数组中的索引,如果不存在,返回-1
*/
public static int getIndex(int[] arr,int value) {
int index = -1;
for(int x=0; x
if(arr[x] == value) {
index = x;
break;
}
}
return index;
}
}
==========================================================================================
4.如何查看API帮助文档
1:打开帮助文档
2:点击显示,找到索引,看到输入框
3:知道你要找谁?以Scanner举例
4:在输入框里面输入Scanner,然后回车
5:看包
java.lang包下的类不需要导入,其他的全部需要导入。
要导入:
java.util.Scanner
6:再简单的看看类的解释和说明,别忘了看看该类的版本
7:看类的结构
成员变量 字段摘要
构造方法 构造方法摘要
成员方法 方法摘要
8:学习构造方法
A:有构造方法 就创建对象
B:没有构造方法 成员可能都是静态的
9:看成员方法
A:左边
是否静态:如果静态,可以通过类名调用
返回值类型:人家返回什么,你就用什么接收。
B:右边
看方法名:方法名称不要写错
参数列表:人家要什么,你就给什么;人家要几个,你就给几个
实例
Math
Math:类包含用于执行基本数学运算的方法
由于Math类在java.lang包下,所以不需要导包。
特点:
没有构造方法,因为它的成员全部是静态的。
掌握一个方法:
获取随机数
public static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
===========================================
class MathDemo {
public static void main(String[] args) {
//获取一个随机数
//double d = Math.random();
//System.out.println(d);
//需求:我要获取一个1-100之间的随机数,肿么办?
for(int x=0; x<100; x++) {
int number = (int)(Math.random()*100)+1;
System.out.println(number);
}
}
}
========================
实例2 /* 猜数字小游戏(1-100) */ import java.util.Scanner; class GuessNumber { public static void main(String[] args) { //程序产生一个随机数 int number = (int)(Math.random()*100)+1; //给出多次猜的机会,猜中就结束 while(true) { //键盘录入数据 Scanner sc = new Scanner(System.in); System.out.println("请输入你要猜的数据(1-100):"); int guessNumber = sc.nextInt(); if(guessNumber>number) { System.out.println("你要猜的数据"+guessNumber+"大了"); } else if(guessNumber<number) { System.out.println("你要猜的数据"+guessNumber+"小了"); } else { System.out.println("恭喜你,猜中了"); } } } }
/*
2 代码块
3 */
4 class Code
5 {
6
7 }
8 class CodeDemo
9 {
10 public static void main(String[] args)
11 {
12 //局部代码块
13 {
14 int x = 10;//只在大括号内使用
15 System.out.println(x);
16 }
17
18 System.out.println(x);//报错,找不到符号
19 }
20 }
1 class Father
2 {
3 public int num = 10;
4 }
5 class Son extends Father
6 {
7 public int num = 20;
8
9 public void show()
10 {
11 int num = 30;//就近原则
12 System.out.println(num);
13 }
14 }
15
16 class ExtendsDemo5
17 {
18 public static void main(String[] args)
19 {
20 Son s = new Son();
21 s.show();
22 }
23 }
如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
报错。
如何解决呢?
A:在父类中加一个无参构造方法
B:通过使用super关键字去显示的调用父类的带参构造方法
C:子类通过this去调用本类的其他构造方法
子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。
注意事项:
this(...)或者super(...)必须出现在第一条语句上。
如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
(第一条语句给不给它都默认有一个空的super语句,最好手动说明以免引起冲突)
11.一个类的初始化过程
成员变量进行初始化
默认初始化
显示初始化
构造方法初始化
看程序写结果
A:一个类的静态代码块,构造代码块,构造方法的执行流程
静态代码块 > 构造代码块 > 构造方法
B:静态的内容是随着类的加载而加载
静态代码块的内容会优先执行
C:子类初始化之前先会进行父类的初始化
运行结果是:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
*/
1 class Fu {
2 static {
3 System.out.println("静态代码块Fu");
4 }
5
6 {
7 System.out.println("构造代码块Fu");
8 }
9
10 public Fu() {
11 System.out.println("构造方法Fu");
12 }
13 }
14
15 class Zi extends Fu {
16 static {
17 System.out.println("静态代码块Zi");
18 }
19
20 {
21 System.out.println("构造代码块Zi");
22 }
23
24 public Zi() {
25 System.out.println("构造方法Zi");
26 }
27 }
28
29 class ExtendsTest2 {
30 public static void main(String[] args) {
31 Zi z = new Zi();
32 }
33 }
12. A:成员变量的问题
int x = 10; //成员变量是基本类型
Student s = new Student(); //成员变量是引用类型
B:一个类的初始化过程
成员变量的初始化
默认初始化
显示初始化
构造方法初始化
C:子父类的初始化(分层初始化)
先进行父类初始化,然后进行子类初始化。
结果:
YXYZ
问题:
虽然子类中构造方法默认有一个super()
初始化的时候,不是按照那个顺序进行的。
而是按照分层初始化进行的。
它仅仅表示要先初始化父类数据,再初始化子类数据。
例子
1 class X {
2 Y b = new Y();
3 X() {
4 System.out.print("X");
5 }
6 }
7
8 class Y {
9 Y() {
10 System.out.print("Y");
11 }
12 }
13
14 public class Z extends X {
15 Y y = new Y();
16 Z() {
17 //super (注意这里不要加super())
18 System.out.print("Z");
19 }
20 public static void main(String[] args) {
21 new Z();
22 }
23 }
24
25 13.子类方法覆盖父类方法
26 class Father
27 {
28 public void show()
29 {
30 System.out.println("show Father");
31 }
32 }
33
34 class Son extends Father
35 {
36 public void method()
37 {
38 System.out.println("method Son");
39 }
40
41 public void show()
42 {
43 System.out.println("show Son");
44 }
45 }
46 class ExtendsDemo8
47 {
48 public static void main(String[] args)
49 {
50 //创建对象
51 Son s = new Son();
52 s.method();
53 s.show();
54 }
55 }
13.方法重写:子类中出现了和父类中方法声明一模一样的方法。
方法重载:
本类中出现的方法名一样,参数列表不同的方法。与返回值无
子类对象调用方法的时候:
先找子类本身,再找父类。
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
例子
A:定义一个手机类。
B:通过研究,我发明了一个新手机,这个手机的作用是在打完电话后,可以听天气预报。
class Phone {
public void call(String name) {
System.out.println("给"+name+"打电话");
}
}
class NewPhone extends Phone {
public void call(String name) {
//System.out.println("给"+name+"打电话");
super.call(name); //避免重复代码
System.out.println("可以听天气预报了");
}
}
class ExtendsDemo9 {
public static void main(String[] args) {
NewPhone np = new NewPhone();
np.call("林青霞");
}
}
14.方法重写的注意事项
A:父类中私有方法不能被重写
因为父类私有方法子类根本就无法继承
B:子类重写父类方法时,访问权限不能更低(public 高)
最好就一致
C:父类静态方法,子类也必须通过静态方法进行重写
其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中讲解
子类重写父类方法的时候,最好声明一模一样。
15.两个面试题
1:方法重写和方法重载的区别?方法重载能改变返回值类型吗?
方法重写:
在子类中,出现和父类中一模一样的方法声明的现象。
方法重载:
同一个类中,出现的方法名相同,参数列表不同的现象。
方法重载能改变返回值类型,因为它和返回值类型无关。
Override:方法重写
Overload:方法重载
2:this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。
this:代表当前类的对象引用
super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)
场景:
成员变量:
this.成员变量
super.成员变量
构造方法:
this(...)
super(...)
成员方法:
this.成员方法
super.成员方法
16.super
实例
//定义人类
class Person {
//姓名
private String name;
//年龄
private int age;
public Person() {
}
public Person(String name,int age) { //"林青霞",27
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;
}
}
//定义学生类
class Student extends Person {
public Student() {}
public Student(String name,int age) { //"林青霞",27
//this.name = name;
//this.age = age;
super(name,age);
}
}
class ExtendsTest4 {
public static void main(String[] args) {
//创建学生对象并测试
//方式1
Student s1 = new Student();
s1.setName("林青霞");
s1.setAge(27);
System.out.println(s1.getName()+"---"+s1.getAge());
//方式2
Student s2 = new Student("林青霞",27);
System.out.println(s2.getName()+"---"+s2.getAge());
}
补充笔记
API(Application Programming Interface)
应用程序编程接口(帮助文档)
day09
1.final引入
继承的代码体现
由于继承中方法有一个现象:方法重写。
所以,父类的功能,就会被子类给覆盖调。
有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。
这个时候,针对这种情况,Java就提供了一个关键字:final
final:最终的意思。常见的是它可以修饰类,方法,变量。
2.final
final可以修饰类,方法,变量
特点:
final可以修饰类,该类不能被继承。
final可以修饰方法,该方法不能被重写。(覆盖,复写)
final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。
常量:
A:字面值常量
"hello",10,true
B:自定义常量
final int x = 10;
3.final面试题
4.final修饰变量的初始化时机
A:被final修饰的变量只能赋值一次。
B:在构造方法完毕前。(非静态的常量)
5.多态
多态概述
某一个事物,在不同时刻表现出来的不同状态。
通过猫这个小动物,说猫可以被称为猫,也可以被称为动物。在不同时刻,猫表现出的不同状态,来说明多态.
举例:
猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。
动物 d = new 猫();
多态:同一个对象(事物),在不同时刻体现出来的不同状态。
举例:
猫是猫,猫是动物。
水(液体,固体,气态)。
多态的前提:
A:要有继承关系。
B:要有方法重写。
有父类引用指向子类对象
5. 多态中的成员访问特点:
A:成员变量
编译看左边,运行看左边。(意思是编译和运行都是看父类的,都是访问父类的成员,而变量不存在重写,父类的变量不会被子类覆盖)
B:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
C:成员方法
编译看左边,运行看右边。(方法存在覆盖,存在方法重写,父类的方法被子类覆盖)
D:静态方法
编译看左边,运行看左边。(父类的静态方法不会被子类的静态方法所覆盖)
(静态和类相关,算不上重写,所以,访问还是左边的)
由于成员方法存在方法重写,所以它运行看右边。
完整代码
class Fu {
public int num = 100;
public void show() {
System.out.println("show Fu");
}
public static void function() {
System.out.println("function Fu");
}
}
class Zi extends Fu {
public int num = 1000;
public int num2 = 200;
public void show() {
System.out.println("show Zi");
}
public void method() {
System.out.println("method zi");
}
public static void function() {
System.out.println("function Zi");
}
}
class DuoTaiDemo {
public static void main(String[] args) {
//要有父类引用指向子类对象。
//父 f = new 子();
Fu f = new Zi();
System.out.println(f.num);
//找不到符号
//System.out.println(f.num2);
f.show();
//找不到符号
//f.method();
f.function();
}
}
6.
多态的好处:
A:提高了代码的维护性(继承保证)
B:提高了代码的扩展性(由多态保证)
比如有一个父类superClass,它有2个子类subClass1,subClass2。superClass有一个方法
func(),两个子类都重写了这个方法。那么我们可以定义一个superClass的引用obj,让它指向一个子类的对象,比如superClass obj = new subClass1();那么我们调用obj.func()方法时候,会进行动态绑定,也就是obj它的实际类型的func()方法,即subClass1的func()方法。同样你写superClass obj = new subClass2();obj.func()其实调用的是subClass2的func()方法。这种由于子类重写父类方法,然后用父类引用指向子类对象,调用方法时候会进行动态绑定,这就是多态。多态对程序的扩展具有非常大的作用,比如你要再有一个subClass3,你需要改动的东西会少很多,要是使用了配置文件那就可以不动源代码了。
7.多态的弊端:
不能使用子类的特有功能。(因为编译左边)
Fu f = new Zi();//f不能调用Fu中没有而Zi特有的功能
想使用子类的特有功能?行不行?
行。
怎么用呢?
A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
B:把父类的引用强制转换为子类的引用。(向下转型)
对象间的转型问题:
向上转型:
Fu f = new Zi();
向下转型:
Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
实例
class Fu {
public void show() {
System.out.println("show fu");
}
}
class Zi extends Fu {
public void show() {
System.out.println("show zi");
}
public void method() {
System.out.println("method zi");
}
}
class DuoTaiDemo4 {
public static void main(String[] args) {
//测试
Fu f = new Zi();
f.show();
//f.method();
//创建子类对象,太占内存
//Zi z = new Zi();
//z.show();
//z.method();
//你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
//如果可以,但是如下
Zi z = (Zi)f;//强制类型转换
z.show();
z.method();
}
}
多态继承中的内存图解
多态中的对象变化内存图解
/*
2 不同地方饮食文化不同的案例
3 */
4 class Person {
5 public void eat() {
6 System.out.println("吃饭");
7 }
8 }
9
10 class SouthPerson extends Person {
11 public void eat() {
12 System.out.println("炒菜,吃米饭");
13 }
14
15 public void jingShang() {
16 System.out.println("经商");
17 }
18 }
19
20 class NorthPerson extends Person {
21 public void eat() {
22 System.out.println("炖菜,吃馒头");
23 }
24
25 public void yanJiu() {
26 System.out.println("研究");
27 }
28 }
29
30 class DuoTaiTest2 {
31 public static void main(String[] args) {
32 //测试
33 //南方人
34 Person p = new SouthPerson();
35 p.eat();
36 System.out.println("-------------");
37 //转换成南方人
38 SouthPerson sp = (SouthPerson)p;
39 sp.eat();
40 sp.jingShang();
41 System.out.println("-------------");
42
43 //北方人
44 p = new NorthPerson();
45 p.eat();
46 System.out.println("-------------");
47 //转换成北方人
48 NorthPerson np = (NorthPerson)p;
49 np.eat();
50 np.yanJiu();
51 }
52 }
53
abstract class Animal {
2 public int num = 10;//变量
3 public final int num2 = 20;//常量
4
5 public Animal() {}//无参构造方法
6
7 public Animal(String name,int age){}//带参构造方法
8
9 public abstract void show();//抽象方法
10
11 public void method() {//非抽象方法
12 System.out.println("method");
13 }
14 }
15
16 class Dog extends Animal {
17 public void show() {
18 System.out.println("show Dog");
19 }
20 }
21
22 class AbstractDemo2 {
23 public static void main(String[] args) {
24 //创建对象
25 Animal a = new Dog();
26 a.num = 100;
27 System.out.println(a.num);
28 //a.num2 = 200;
29 System.out.println(a.num2);
30 System.out.println("--------------");
31 a.show();
32 a.method();
33 }
34 }
class Outer {
2 private int num = 10;
3
4 public void method() {
5 //int num2 = 20;
6 //final int num2 = 20;
7 class Inner {
8 public void show() {
9 System.out.println(num);
10 //从内部类中访问本地变量num2; 需要被声明为最终类型
11 System.out.println(num2);//20
12 }
13 }
14
15 //System.out.println(num2);
16
17 Inner i = new Inner();
18 i.show();
19 }
20 }
21
22 class InnerClassDemo5 {
23 public static void main(String[] args) {
24 Outer o = new Outer();
25 o.method();
26 }
27 }
interface Inter {
2 public abstract void show();
3 public abstract void show2();
4 }
5
6 class Outer {
7 public void method() {
8 //一个方法的时候
9 /*
10 new Inter() {
11 public void show() {
12 System.out.println("show");
13 }
14 }.show();
15 */
16
17 //二个方法的时候
18 /*注释中是一个一个调用
19 new Inter() {
20 public void show() {
21 System.out.println("show");
22 }
23
24 public void show2() {
25 System.out.println("show2");
26 }
27 }.show();
28
29 new Inter() {
30 public void show() {
31 System.out.println("show");
32 }
33
34 public void show2() {
35 System.out.println("show2");
36 }
37 }.show2();
38 */
39
40 //如果我是很多个方法,就很麻烦了
41 //那么,我们有没有改进的方案呢?
42 Inter i = new Inter() { //多态
43 public void show() {
44 System.out.println("show");
45 }
46
47 public void show2() {
48 System.out.println("show2");
49 }
50 };
51
52 i.show();
53 i.show2();
54 }
55 }
56
57 class InnerClassDemo6 {
58 public static void main(String[] args) {
59 Outer o = new Outer();
60 o.method();
61 }
62 }
63