①Java类及类的成员:属性、方法、构造器;代码块、内部类
②面向对象的三大特征:封装性、继承性、多态性、(抽象性)
③其他关键字:this,super,abstract,final,static,import,interface,package等
“大处着眼,小处着手”
1.面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
2.面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
//面向过程 /*①把冰箱打开 * ②抬起大象,塞进冰箱 * ③把冰箱门关闭 */ //面向对象 /*人{ * 打开(冰箱门){ * 冰箱.开开(); * } * 抬起(大象){ * 大象.进入(冰箱); * } * 关闭(冰箱){ * 冰箱.闭合(); * } * } * 冰箱{ * 开开(){} * 闭合(){} * } * * 大象{ * 进入(冰箱){ * * } * } */
根据问题需要,选择问题所针对的现实世界中的实体。
从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
类:对一类事物的描述,是抽象的、概念上的定义
对象:是实际存在的该类实物的每个个体,因而也称为实例(instance)
--面向对象程序设计的重点是类的设计
--设计类,就是设计类的成员
二者的关系:
对象,是由类new出来的,派生出来的。
1.创建类,设计类的成员
2.创建类的对象
3.通过“对象.属性”或“对象.方法”调用对象的结构
补充:几个概念的使用说明
属性=成员变量=field=域、字段
方法=成员方法=函数=method
创建类的对象=类的实例化=实例化类
典型代码:
Person p1=new Person(); Person p2=new Person(); Person p3=p1;//没有新创建一个对象,共用一个堆空间中的对象实体。
说明:
如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)
意味着:如果我们修改一个对象的属性a,则不影响另一个对象属性a的值
理解:我们创建的对象,没有显式的赋给一个变量名,即为匿名对象。
特征:匿名对象只能调用一次。
举例:
//匿名对象 new Phone().sendEmail(); new Phone().playGame(); new Phone().price=1999; new Phone().showPrice();//0.0
应用场景:
PhoneMall mall=new PhoneMall(); //匿名对象的使用 mall.show(new Phone()); //其中 class PhoneMall{ public void show(Phone phone) { phone.sendEmail(); phone.playGame(); } }
1.在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
Scanner,String等
文件:File
网络资源:URL
2.涉及到Java语言与前端Html、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。
编译完源程序以后,生成一个或多个字节码文件。
我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。
推荐书籍:《JVM规范》
虚拟机栈,即为平时提到的栈结构。我们将局部变量存储在栈结构中。
堆:我们将new出来的结构(比如:数组、对象)加载在堆空间中。补充:对象的属性(非static中)加载在堆空间中。
方法区:类的加载信息、常量池、静态域
属性(成员变量)VS局部变量
1.相同点:
1.1定义变量的格式:数据类型 变量名=变量值
1.2先声明,后使用
1.3变量都有其对应的作用域
2.不同点:
2.1在类中声明的位置的不同
属性:直接定义在类的一对{}中
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2.2关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符
常用的权限修饰符:private、public、确省、protected------>封装性
局部变量:不可以使用权限修饰符
2.3默认初始化值的情况:
属性:类的属性,根据其类型,都有默认初始化值。
整型(byte、short、int、long):0
浮点型(float、double):0.0
字符型(char):0(或'\u0000')
布尔型(boolean):false
引用数据类型(类、数组、接口):null
局部变量:没有默认初始化值
意味着,我们在调用局部变量之前,一定要显式赋值。
特别地:形参在调用时,我们赋值即可
2.4在内存中加载的位置
属性:加载到堆空间中(非static)
局部变量:加载到栈空间.
方法:描述类应该具有的功能
比如:Math类:sqrt()\random()\。。。。
Scanner类:nextXxx().......
Array类:sort()\binarySearch()\toString()\quals()\。。。。。
1.举例:
public void eat(){} public void sleep(int hour){} public String getName(){} public String getNation(String nation){}
2.方法的声明:权限修饰符 返回值类型 方法名(形参列表){
方法体;
}
注意:static、final、abstract来修饰的方法,后面再讲
3.说明:
3.1关于权限修饰符:默认方法的权限修饰符先都使用public
Java规定的4种权限修饰符:public、private、缺省、protected--->封装性再细说
3.2返回值类型: 返回值 VS 没返回值
3.2.1如果方法返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量:“return 数据”
如果方法没返回值,则方法声明时,使用void来表示,通常,没返回值的方法中,就不需要使用return。但是,如果使用的话,只能“return”,表示结束此方法的意思。
3.2.2我们定义方法该不该返回值?
①根据题目要求
②凭经验:具体问题具体分析
3.3方法名:属于标识符,遵循标识符的规则和规范:“见名知意”
3.4形参列表:方法可以声明0个、1个或多个形参
3.4.1格式:数据类型1 形参1,数据类型2 形参2,.....
3.4.2我们定义方法是,该不该定义形参?
①根据题目要求
②凭经验:具体问题具体分析
3.5方法体:方法功能的实现
4.return关键字的使用
1.适用范围:使用在方法体中
2.作用:①结束方法
②针对有返回值类型的方法,使用“return 数据”方法返回所要的数据
3.注意点:return关键字后不可以声明执行语句。
5.方法的使用中,可以调用当前类的属性或方法。
特殊的:方法A中又调用了方法A:递归方法。
方法中,不可以定义方法。
1.方法的重载的概念
定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
"两同一不同":同一个类,相同方法名
参数列表不同:参数个数不同,参数类型不同
2.构成重载的举例:
举例一:Arrays类中重载sort()/binarySearch();
举例二:
//如下的4个方法构成了重载 public void getSum(int i,int j) { System.out.println("1"); } public void getSum(double d1,double d2) { System.out.println("2"); } public void getSum(String s,int i) { System.out.println("3"); } public void getSum(int i,String s) { System.out.println("4"); }
不构成重载的举例:
//错误重载,下列三种不能与上述4个方法构成重载 /* public int getSum(int i,int j) { return 0; } */ /*public void getSum(int m,int n) { } */ // private void getSum(int i,int j) { // // }
3.如何判断是否构成方法的重载?
严格按照定义判断:两同一不同。
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
4.如何确定类中某一个方法的调用
方法名---->参数列表
面试题:方法的重载于重写的区别?
throws\throw
String\stringBuffer\StringBuilder
collection\collections
final \finally\finalize
............
抽象类、接口
sleep()/wait()
1.使用说明
1.jdk 5.0新增的内容
2.具体使用
2.1可变个数形参的格式:数据类型...变量名
2.2当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个.....
2.3可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
2.4可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。即,不可共存
2.5可变个数形参在方法的形参中,必须声明在末尾
2.6可变个数形参在方法的形参中,最多只能声明一个可变形参
2.举例说明:
public void show(int i) { } public void show(String s) { System.out.println("show(String)"); } public void show(String...strs) { System.out.println("show(String...strs)"); for(int i=0;i<strs.length;i++) { System.out.println(strs[i]); } } //编译不通过,不能与上一个方法同时存在 // public void show(String[]strs) { // } //编译不通过 说明:2.5 //The variable argument type String of the method //show must be the last // public void show(String...strs,int i) { // // }
3.调用时:
test.show(12); test.show("hello"); test.show("hello","world"); test.show();//可以为0个 test.show("aa","bb","cc"); test.show(new String[] {"aa","bb","cc"});
1.针对于方法内变量的赋值举例:
System.out.println("**********基本数据类型**********"); int m=10; int n=m; System.out.println("m="+ m + ",n="+n); n=20; System.out.println("m="+ m + ",n="+n); System.out.println("**********引用数据类型*********"); Order o1=new Order(); o1.orderId=1001; Order o2=o1;//赋值以后:o1和o2的地址值相同,都指向了堆空间中同一个对象实体 System.out.println("o1.orderId="+o1.orderId+",o2.orderId="+o2.orderId); o2.orderId=1002; System.out.println("o1.orderId="+o1.orderId+",o2.orderId="+o2.orderId); } class Order{ int orderId; }
规则:
如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
2.针对于方法的参数概念
形参:方法定义时,声明的小括号内的参数
实参:方法调用时,实际传递给形参的数据
3.Java中参数传递机制:值传递
规则:
如果参数是基本数据类型,此时实参赋给形参的是,实参真是存储的数据值。
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
推广:
如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
4.典型例题与内存解析:
例题1:
例题2:
1.定义
递归方法:一个方法体调用它自身
2.如何理解递归方法?
方法递归包含了一种隐式循环,它会重复执行某段代码,但这种重复执行无须循环控制。
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
3.举例:
//例1:计算1-100之间所有的自然数的和 //方式一: // int sum=0; // for(int i=1;i<=100;i++) { // sum+=i; // } RecursionTest test=new RecursionTest() ; System.out.println(test.getSum(100)); System.out.println(test.getSum1(2)); System.out.println("***************************"); int value=test.f(10); System.out.println(value); } //方式二:计算1-n之间所有自然数的和 public int getSum(int n) { if(n==1) { return 1; }else { return n+getSum(n-1); } } //例2:计算1-n之间所有自然数的乘积 public int getSum1(int n) { if(n==1) { return 1; }else { return n*getSum1(n-1); } } //例3:已知有一个数列:f(0)=1,f(1)=4,f(n+2)=2*f(n-1)+f(n), //其中n是大于0的整数,求f(10)的值。 public int f(int n) { if(n==0) { return 1; }else if(n==1) { return 4; }else { return 2*f(n-1)+f(n-2); } } //例4:输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值 //例5:汉诺塔问题 //例6:快排