4.面向对象编程(上)
Java面向对象学习的三条主线:(第4-6章)
- 1.Java类及类的成员:属性、方法、构造器;代码块、内部类
- 2.面向对象的三大特征:封装性、继承性、多态性、(抽象性)
- 3.其它关键字:this.、super、 static、final、abstract、interface、package、import
4.1面向过程与面向对象
二者都是一种思想,面向对象是相对于面向过程而言的。
面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。
面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如抽象、分类、继承、聚合、多态等。
4.2基本要素
- 类(Class)和对象(Object)是面向对象的核心概念。
- 类是对一类事物的描述,是抽象的、概念上的定义
- 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)
4.2.1类的结构
设计类就是设计类的成员:属性和方法(主要结构)
属性=成员变量=field=域=字段
方法=成员方法=函数=method
创建类的对象=类的实例化=实例化类
完整结构
4.2.2类中属性的使用
4.2.2.1属性(成员变量)和局部变量的异同
- 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(或’\ue000’)
- 布尔型(boolean):false
- 引用数据类型(类、数组、接口):null
- 局部变量:没有默认初始化值。
- 意味着,我们在调用局部变量之前,一定要显式赋值,否则会报错。
- 特别地:形参在调用时,我们赋值即可。
- 属性:类的属性,根据其类型,都有默认初始化值。
- 2.4在内存中加载的位置不同
- 属性:加载到堆空间中(非static属性)
- 局部变量:加载到栈空间
- 2.1在类中声明的位置的不同
4.2.3类中方法的声明和使用
4.2.3.1方法的声明:
权限修饰符 返回值类型 方法名(形参列表){
方法体
}
注意:static、final、abstract来修饰的方法,后面再讲。
说明
- 权限修饰符
- Java规定的4种权限修饰符:private、public、缺省、protected
- 返回值类型:有返回值、无返回值
- 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量。“return 返回值;”
- 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不必使用return。但是,如果使用的话,只能"return;”表示结束此方法的意思。
- 形参列表
- 形参列表:方法可以声明0个,1个,或多个形参。
- 格式:数据类型1 形参1,数据类型2 形参2,…
4.2.3.2return关键字的使用:
- 1.使用范围:使用在方法体中
- 2.作用:
- 结束方法
- 针对于有返回值类型的方法,使用"return 返回值"方法返回所要的数据。
- 3.注意点: return关键字后面不可以声明执行语句。
4.2.3.3方法的使用
- 可以使用本方法中的属性和方法
- 特殊的:A方法调用A方法称为递归调用
- 方法中不能定义方法
4.3对象的创建和使用
4.3.1步骤
1.创建类,设计类的成员
2.创建类的对象
3.通过"对象.属性"或"对象.方法"调用对象的结构
注意:如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。
4.3.2对象的内存解析
4.3.3匿名对象的使用
理解:我们创建的对象,没有显式的赋给一个变量名。即为匿名对象
特征:匿名对象只能调用一次。
4.3.4练习
P194
package com.atguigu.classes.test;
public class StudentTest {
public static void main(String[] args) {
Student[] students=new Student[20];
for(int i=0;i<students.length;i++) {
Student stu=new Student();
stu.number=i+1;
//[1,6]
stu.state=(int)(Math.random()*(6-1+1)+1);
//[0,100]
stu.score=(int)(Math.random()*(100-0+1)+0);
students[i]=stu;
//打印三年级学生信息
if(stu.state==3)
stu.getMessage();
}
//按分数从小到大冒泡排序
for(int i=students.length-1;i>0;i--) {
for(int j=0;j<i;j++) {
if(students[j].score>students[j+1].score) {
Student temp=students[j+1];
students[j+1]=students[j];
students[j]=temp;
}
}
}
//遍历所有学生的信息
System.out.println();
for(int i=0;i<students.length;i++)
students[i].getMessage();
}
}
class Student{
int number;//学号
int state;//年级
int score;//分数
public void getMessage() {
System.out.println("学号:"+number+"\t"+"年级:"+state+"\t"+"分数:"+score);
}
}
4.4day08每日一考
理解万事万物皆对象”
- 1.在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
- Scanner, string等
- 文件:File
- 网络资源:URL
- ⒉.涉及到Java语言与前端HTML、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。
4.5类的成员-方法
4.5.1方法的重载
4.5.1.1重载的概念
- 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
重载的特点︰
- 与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
4.5.1.2重载示例
- /返回两个整数的和
int add(int x,int y){return x+y;} - //返回三个整数的和
int add(int x,int y,int z){return x+y+z;} - //返回两个小数的和
double add(double x,double y){return x+y;}
4.5.1.3判断是否是重载:
- 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
4.5.2可变形参的方法
JavaSE 5.0中提供了Varargs(variable number of arguments)机制,允许直接义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。
//JDK5.0以前:采用数组形参来定义方法,传入多个同一类型变量
public static void test(int a ,String[] books);
//JDK5.0:采用可变个数形参来定义方法,传入多个同一类型变量
public static void test(int a ,String…books);
4.5.2.1可变形参的具体使用
- 2.1 可变个数形参的格式:数据类型…变量名
- 2.2 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,。。。
- 2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
- 2.4可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存;
- 2.5可变个数形参在方法的形参中,必须声明在末尾
- 2.6可变个数形参在方法的形参中,最多只能声明一个可变形参。
package com.atguigu.classes.test;
public class VariableArgumentsTest {
public static void main(String[] args) {
Test t=new Test();
//调用函数1,如果将1注释,也不会报错,会自动类型转换后调用2
t.show(1);
//只能调用4
t.show("AA","B","d");
//可以调用4也可以调用7(4和7不能共存)
t.show(new String[] {"AA","B","d"});
}
}
class Test{
//1.
public void show(int i) {}
//2.
public void show(double d) {}
//3.
public int show(String str) {return 0;}
//4.JDK5.0的可变形参(两种写法只能选一种,否则会报错)
public void show(String ...strs) {
//遍历多个可变形参的方法和数组一样
for(int i=0;i<strs.length;i++)
System.out.println(strs[i]);
};
//5.报错:JDK5.0的写法要求可变形参只能有一个,且要放到最后
public void show(String...strs,int i) {}
//6.无报错
public void show(int i,String...strs) {}
//7.JDK5.0之前可变形参的写法(两种写法只能选一种,否则会报错)
public void show(String[] strs) {};
//8.JDK5.0之前的写法,可变形参的位置、个数没有要求
public void show(String[] strs1,String[] strs2,int i) {};
}
4.5.3方法参数的值传递机制
4.5.3.1变量的赋值
- 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
- 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
4.5.3.2方法形参的值传递机制
- 形参:方法定义时,声明的小括号内的参数
- 实参:方法调用时,实际传递给形参的数据
- 值传递机制
- 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。形参值改变不会影响实参的值
- 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
4.5.3.2方法值传递练习
P213
4.5.4递归方法
递归方法:一个方法体内调用它自身。
方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
public int getSum(int n){
if(n==1){
return 1;
}else{
return n+getSum(n-1);
}
}
4.5.4.1练习
package com.atguigu.classes.test;
//递归练习
public class RecursionTest {
public static void main(String[] args) {
RecursionTest rec=new RecursionTest();
System.out.println(rec.Method(10));
System.out.println(rec.Fibonacci(10));
}
//例3:已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),
//其中n是大于日的整数,求千(10)的值。
public int Method(int n) {
if(n==0)
return 1;
else if(n==1)
return 4;
else
return 2*Method(n-1)+Method(n-2);
}
//练习4:输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值
//1 1 2 3 5 8 13 21 34 55
//规律:一个数等于前两个数之和
//要求:计算斐波那契数列(Fibonacci)的第n个值,并将整个数列打印出来
public int Fibonacci(int n) {
if(n==1||n==2)
return 1;
else
return Fibonacci(n-1)+Fibonacci(n-2);
}
}
4.6day09每日一考
P218
4.7封装与隐藏
我们程序设计追求“高内聚,低耦合”。
高内聚:类的内部数据操作细节自己完成,不允许外部干涉;>低耦合:仅对外暴露少量的方法用于使用。
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
4.7.1封装性的体现
- 我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)属性
- 不对外暴露私有的方法
- 单例模式(后面讲)
- 封装性的体现,需要权限修饰符来配合。
ava规定的4种权限(从小到大排列): private、缺省、protected . public
4.7.2四种访问权限修饰符
4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
修饰类的话,只能使用:缺省、public
4.8类的成员-构造器(构造方法)
4.8.1构造器的作用
创建对象和初始化类的属性(有参构造器)
//创建Scanner类的对象:new +构造器
Scanner scan=new Scanner()
4.8.2说明
- 如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
- 一旦我们显式的定义了类的构造器(无论是否是空参构造器)之后,系统就不在提供默认的空参构造器
- 定义构造器的格式:权限修饰符 类名(形参列表)
- 一个类中定义的多个构造器,彼此构成重载
4.8.3构造器的特征
- 它具有与类相同的名称
- 它不声明返回值类型。(与声明为void不同)
- 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
4.8.4构造器的作用
- 创建对象
- 给对象初始化
4.8.5类属性赋值的先后顺序
①默认初始化
②显式初始化
③构造器中赋值
④通过"对象.方法"或"对象.属性"的方式,赋值
4.9JavaBean
JavaBean是一种Java语言写成的可重用组件。
所谓JavaBean,是指符合如下标准的Java类:
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、 set方法
4.10UML类图
- 1.+表示public类型,-表示private类型,#表示protected类型
- 2.方法的写法:
方法的类型(+、-) 方法名(参数名:参数类型):返回值类型
4.11关键字
4.11.1this的使用
1.this可以用来修饰:属性、方法、构造器
2.this修饰属性和方法:
this理解为:当前对象或当前正在创建的对象
- 2.1在类的方法(构造器)中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象(正在创建的对象)属性或方法。但是通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
- 调用构造器的形式:如果没有参数this();如果有参数this(形参列表)
- 构造器的this
- 调用必须放在首行
- 注意再用this相互调用时,写成死循环
4.11.2package
4.11.2.1使用
- 为了更好的实现项目中类的管理,提供包的概念
- 使用package声明类或接口所属的包,声明在源文件的首行
- 这个首航前面可以有空格或回车,而xml文件中所受的首行的前面不能有,注意区分
- 包名,属于标识符,遵循标识符的命名规则、规范(xxx.yyy.zzz)、“见名知意”
- 每"."一次,就代表一层文件目录。
- 同一个包下,不能命名同名的接口、类。
- 不同的包下,可以命名同名的接口、类。
4.11.2.2JDK中主要的包的介绍
java.lang----包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能
java.net----包含执行与网络相关的操作的类和接口。java.io ----包含能提供多种输入/输出功能的类。
java.util----包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。
java.text----包含了一些java格式化相关的类
java.sql----包含了java进行JDBC数据库编程的相关类/接口
java.awt----包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUIl)。B/Sc/s
4.11.3import
-
在源文件中显式的使用import结构导入指定包下的类、接口
-
import声明在包的声明和类的声明之间
-
如果需要导入多个结构,则并列写出即可
-
如果要使用的多个结构都在xxx包下面,则可以使用xxx.*"的方式,表示可以导入xxx包下的所有结构
-
如果使用的类或接口是java. lang包下定义的,则可以省略import结构
-
如果使用的类或接口是本包下定义的,则可以省略import结构
-
如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示。
-
Date date = new Date();//这个是java.util包下的Date采用import的方式 java.sql.Date date1 = new java.sql.Date(5243523532535L);//这个是java.sql下的Date,由于上面的用过import了,所以只能用这种形式
-
-
使用"xxx.*"方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显导入
-
import static:导入指定类或接口中的静态结构。
4.12MVC设计模式
MVC是常用的设计模式之一,将整个程序分为三个层次:视图模型层,控制器层,与数据模型层。这种将程序输入输出、数据处理,以及数据的展示分离开来的设计模式使程序结构变的灵活而且清晰,同时也描述了程序各个对象间的通信方式,降低了程序的耦合性。
模型层 model主要处理数据
- 数据对象封装model.bean/domain
- 数据库操作类model.dao
- 数据库model.db
控制层 controller处理业务逻辑
- 应用界面相关controller.activity
- 存放fragment controller.fragment
- 显示列表的适配器controller.adapter
- 服务相关的controller.service
- 抽取的基类controller.base
视图层 view显示数据
- 相关工具类view.utils
- 自定义view view.ui