文章目录
7、面向对象编程(上)
学习面向对象内容的三条主线
1、Java类及类的成员
2、面向对象的三大特征
3、其他关键字
-
Java类及类的成员
- 属性、方法、构造器;代码块、内部类
-
面向对象的三大特征
- 封装性、继承性、多态性、(抽象性)
-
其他关键字
- this\super\static\final\abstract\interface\package\import等
7.1、面向过程(POP)和面向对象(OOP)
二者都是一种思想,面向对象是相对于面向对象而言的。面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
面向对象更加强调运用人类在日常思维逻辑中采用的思想方法和原则,如抽象、分类、继承、聚合、多态等。
面向对象的三大特征:
封装 (Encapsulation)
继承 (Inheritance)
多态 (Polymorphism)
面向对象:Object Oriented Programming
面向过程: Procedure Oriented Programming
二、“人把大象装进冰箱”
1、面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做
- 把冰箱门打开
- 抬起大象,塞进冰箱
- 把冰箱门关闭
2、面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
人{
打开(冰箱)
冰箱.打开();
抬起(大象){
大象.进入(冰箱);
}
}
冰箱 {
冰箱.打开();
冰箱.闭合();
}
大象 {
进入(冰箱){
}
}
面向对象的思想概述
程序员从面向过程的执行者转化成了面向对象的指挥者
面向对象分析方法分析问题的思路和步骤:
- 根据问题需要,选择问题所针对的现实世界中的实体。
- 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
- 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
- 把类实例化成计算机世界中的对象,对象是计算机世界中解决问题的最终工具。
7.2、类和对象
面向对象的思想概述:
类(Class)和 对象(Object)是面向对象的核心概念。
- 类是对一类事物的描述,是抽象的、概念上的定义
- 对象是实际存在的该类事物的每个个体,因而也被称为实例(instance)
“万事万物皆对象”
可以理解为:类=抽象概念的人;对象=实实在在的某个人
面向对象程序设计的重点是类的设计
类的设计,其实就是类的成员的设计
7.1、类的结构:属性和方法
属性: 对应类中的成员变量
行为:对应类中的成员方法
Field = 属性 = 成员变量, Method = (成员)方法 = 函数
/*
* 设计类,其实就是设计类的成员
* 属性 = 成员变量 = field = 域、字段
* 方法 = 成员方法 = 函数 = method
*
*
*/
Java类及类的成员
如何使用Java类?
Java类的实例化,即创建类的对象
二、类和对象的使用(面向对象思想落地的实现):
1、创建类,设计类的成员
2、创建类的对象
3、通过“对象.属性“ 或”对象.方法”调用对象的结构
package test;
//创建类的对象 = 类的实例化 = 实例化类
public class PersonTest {
public static void main(String[] args) {
//创建Person类的对象
Person p1 = new Person();
//类似Scanner scanner = new Scanner(System.in);
//调用对象的结构: 属性、方法
//调用属性: “对象.属性”
p1.name = "Tom";
p1.isMale = true;
System.out.println(p1.name);
//调用方法:“对象.方法”
p1.eat();
p1.sleep();
p1.talk("Chinese");
}
}
class Person{
//属性
String name;
int age = 1;
boolean isMale;
//方法
public void eat() {}
public void sleep() {}
public void talk(String language) {}
}
三、如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)
意味着: 如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。
package test;
//创建类的对象 = 类的实例化 = 实例化类
public class PersonTest {
public static void main(String[] args) {
//创建Person类的对象
Person p1 = new Person();
//类似Scanner scanner = new Scanner(System.in);
//调用对象的结构: 属性、方法
//调用属性: “对象.属性”
p1.name = "Tom";
p1.isMale = true;
System.out.println(p1.name);
//调用方法:“对象.方法”
p1.eat();
p1.sleep();
p1.talk("Chinese");
Person p2 = new Person();
System.out.println(p2.name);//null
System.out.println(p2.isMale);//false
//将p1变量保存的对象地址值赋给p3,导致p1和p3指向了堆空间中的同一个对象实体。
Person p3 = p1;
System.out.println(p3.name);//Tom
p3.age = 10;
System.out.println(p1.age);//10
}
}
class Person{
//属性
String name;
int age = 1;
boolean isMale;
//方法
public void eat() {}
public void sleep() {}
public void talk(String language) {}
}
四、对象的内存解析
7.2、属性与局部变量对比
/*
* 类中属性的使用
*
* 属性(成员变量) 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)
* 局部变量:
* 加载到栈空间
*/
public class UserTest {
public static void main(String[] args) {
}
}
class User{
//属性(或成员变量)
private String name;
public int age;
protected boolean isMale;
public void talk(String language) {//此处的language:形参,属于局部变量
System.out.println("我们使用"+language+"进行交流");
}
public void eat() {
String food = "烙饼";//声明定义在方法内,是局部变量
System.out.println("北方人喜欢吃"+food);
}
}
7.3、类中的方法(method)
方法的分类:按照是否有形参及返回值
无返回值 | 有返回值 | |
---|---|---|
无形参 | void 方法名(){} | 返回值的类型 方法名(){} |
有形参 | void 方法名(形参列表){} | 返回值的类型 方法名(形参列表){} |
/*
* 类中方法的声明和使用
*
* 方法:
* 描述类应该具有的功能
* 比如:
* Math类:sqrt() \ random() \...
* Scanner类: nextXxx()...
* Arrays类: sort() \ binarySearch() \ toString() \ equals() \ ....
* 1.举例:
* public void eat(){}
* public void sleep(int hour) {}
* String getName(){}
* public String getNation(String nation){}
*
*
* void的位置表示返回值类型,void表示没有返回值,String表示返回一个String类型的
* int hour的位置是形参的位置,可以没有
*
* Ctrl+shift+T 输入Arrays/Math可以打开这个类
* Ctrl+O 输入sort/random,可以查看此方法
*
* 2.方法的声明:权限修饰符 返回值类型 方法名(形参列表){
* 方法体
* }
* 注意:static、final、abstract 来修饰的方法,后面再讲。
*
* 3.说明:
* 3.1 关于权限修饰符:
* Java规定的4种权限修饰符:
* private、public、缺省、protected---->封装性再细说。
*
* 3.2 返回值类型:有返回值 VS 没有返回值
* 3.2.1 如果方法有返回值,则必须在方法声明时,指定返回值的类型。
* 同时,方法中,需要使用return关键字来返回指定类型的变量或常量: “return 数据”。
*
* 如果方法没有返回值,则方法声明时,使用void来表示。
* 通常,没有返回值的方法中,就不需要return了,
* 但是,如果使用的话,只能“return;”表示结束此方法的意思。
* 3.2.1 我们定义方法该不该有返回值?
* 1、题目要求
* 2、凭经验: 具体问题具体分析
*
*
* 3.3 方法名: 属于标识符,遵循标识符的规则和规范,“见名知意”
*
* 3.4 形参列表: 方法可以声明0个,1个,或多个形参。
* 3.4.1 格式:
* 数据类型1 形参1,数据类型2 形参2,......
* 3.4.2 我们定义方法时,该不该定义形参?
* 1、题目要求
* 2、凭经验: 具体问题具体分析
* 3.5 方法体
* 方法功能的体现。
*
*
* 4、return关键字的使用:
* 1、使用范围:使用在方法体中
* 2、作用:
* ① 结束方法 “return;”
* ② 针对于有返回值类型的方法,使用“return 数据”方法,返回所要的数据。
* 3、注意点:
* return关键字后面不可以声明执行语句。
*
* 5、方法的使用中,可以调用当前类的属性或方法。
* 特殊的,方法A中又调用了方法A:递归方法。
* 方法中,不可以定义方法。
*/
public class CustomerTest {
public static void main(String[] args) {
Customer cust1 = new Customer();
cust1.eat();
}
}
class Customer{
//属性
String name;
int age;
boolean isMale;
//方法
public void eat() {
System.out.println("客户吃饭");
}
public void sleep(int hour) {
System.out.println("休息了"+hour+"个小时");
}
public String getName() {
/*
* if(age > 18){
* return name;
* }不行,必须返回。
*
*/
return name;
//return "Tom";
}
public String getNation(String nation) {
String info = "我的国籍是:"+nation;
return info;
}
}
7.4、理解“万事万物皆对象”
一、理解“万事万物皆对象”
1、在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
> Scanner,String等
>文件,File
>网络资源,URL
2、涉及到Java语言和前端HTML、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。
7.5、对象数组的内存解析
内存解析说明:
1、引用类型的变量,只可能存储两类值 null 或 地址值(含变量的类型)
对象数组
7.6、匿名对象的使用
理解:
我们创建的对象,没有显式的赋给一个变量名。即为匿名对象
特征:
匿名对象只能调用一次
package test;
public class InstanceTest {
public static void main(String[] args) {
Phone p = new Phone();
System.out.println(p);
p.playGame();
p.sendEmail();
//匿名对象
new Phone().sendEmail();
new Phone().playGame();
new Phone().price=1999;
new Phone().showPrice();//0.0
PhoneMall mall = new PhoneMall();
//mall.show(p);
//匿名对象的使用。
mall.show(new Phone());
}
}
class Phone{
double price;
public void sendEmail() {}
public void playGame() {}
public void showPrice(){
System.out.println("手机价格是:"+price);
}
}
class PhoneMall{
public void show(Phone phone) {
phone.sendEmail();
phone.playGame();
}
}
7.7、再谈方法
7.7.1、 方法的重载
方法的重载(overload) loading…
1.定义:
在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
- “两同一不同”:
- 同一个类、相同方法名
- 参数列表不同
举例:
Arrays类中重载的sort() / binarySearch()
public class OverLoadTest {
//如下四个方法构成了重载
public void getSum(int i ,int j) {
System.out.println(i+j);
}
public void getSum(double d1, double d2) {
System.out.println(d1+d2);
}
public void getSum(String s,int i) {
}
public void getSum(int i,String s) {
}
}
3、判断是否是重载:
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系。
4、在通过对象调用方法时,如何确定某一个指定的方法:
方法名 —>参数列表(可以自动类型提升)
7.7.2、 可变个数的形参
JavaSE 5.0中提供了Varargs(variable number of arguments)机制允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参
//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量
public static void test(int a,String[] books);
//JDK 5.0:采用可变个数形参来定义方法,传入多个同一类型变量
public static void test(int a,String…books);
package com.test.dm;
/*
* 可变个数形参的方法
*
* 1、JDK 5.0新增内容
* 2、具体使用:
* 2.1 可变个数形参的格式,数据类型...变量名
* 2.2 当调用可变个数形参的方法时,传入的参数个数可以是: 0个,1个,多个...
* 2.3 可变个数形参的方法与本类中的方法名相同,形参不同的方法之间构成重载
* 2.4 可变个数形参的方法与本类中的方法名相同,形参类型也相同的数组之间不构成重载,换句话说,两者不可共存。
* 2.5 可变个数形参在方法的形参中,必须声明在末尾。The variable argument type String of the method show
* must be the last parameter
* 2.6 可变个数形参在方法的形参中,最多只能声明一个可变形参。
*/
public class MethodArgsTest {
public static void main(String[] args) {
MethodArgsTest test = new MethodArgsTest();
test.show(12);
test.show("hello");
test.show();
test.show("hello","world");
}
public void show(int i) {}
//public void show(String s) {}
public void show(String ...strs) {
for(int i = 0;i < strs.length;i++) {
System.out.println(strs[i]);
}
}
public void show(int i,String ...strs) {}
//public void show(String[] strs) {}与上面冲突Duplicate method show(String[]) in type MethodArgsTest
//如果调用形参为数组:test.show(new String[]{"AA","BB"});也可以用来调用public void show(String ...strs) 一般直接传字符串不用new
}
7.7.3、方法参数的值传递机制
方法,必须由其所在类或对象调用才有意义。若方法含有参数:
- 形参:方法声明时的参数
- 实参:方法调用时,实际传给形参的参数值
Java的实参值如何传入方法呢?
Java里方法的参数传递方式只有一种:值传递。
即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
- 形参是基本数据类型: 将实参基本数据类型变量的“数据值”传递给形参
- 形参是引用数据类型: 将实参引用数据类型变量的“地址值”传递给形参
package com.test.dm;
/*
*
* 关于变量的赋值
*
*
*/
public class ValueTransferTest {
public static void main(String[] args) {
int m = 10;
int n = m;
System.out.println("m="+m+",n="+n);
n=20;
System.out.println("m="+m+",n="+n);
//引用数据类型
Order o1 = new Order();
o1.orderId = 1001;
Order o2 = o1;
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;
}
7.7.4、递归方法
递归(recursion)方法
递归方法:
- 一个方法体内调用它自身。
方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
递归一定要向己知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
//计算1-100之间所有自然数的和
public int sum(int num) {
if(num == 1) {
return 1;
}else {
return num+sum(num-1);
}
}
package com.test.dm;
/*
* 递归方法的使用(了解)
* 1、递归方法:一个方法体内调用它自身。
* 2、方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
* 递归一定要向己知方向递归,否则这种递归就变成了无穷递归,类似于死循环
*
*/
public class RecursionTest {
public static void main(String[] args) {
//方式一
int sum = 0;
for(int i = 1;i <= 100;i++) {
sum += i;
}
//方式二
RecursionTest test = new RecursionTest();
System.out.println(test.sum(100));
System.out.println(test.sum1(10));
}
//计算1-100之间所有自然数的和
public int sum(int num) {
if(num == 1) {
return 1;
}else {
return num+sum(num-1);
}
}
//计算1-10之间所有自然数的乘积: n!
public int sum1(int num1) {
if(num1 == 1) {
return 1;
}else {
return num1*sum1(num1-1);
}
}
}
7.3、面向对象特征之一:封装与隐藏
我们程序设计追求“高内聚,低耦合”
- 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
- 低耦合:仅对外暴露少量的方法用于使用。
隐藏对象内部复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。
package com.test.dm01;
/*
* 面向对象的特征之一:封装与隐藏
*
* 一、问题的引入:
* 当我们创建一个类的对象以后,
* 我们可以通过“对象.属性”的方式,对对象的属性进行赋值。
* 这里,赋值操作要受到属性的数据类型和存储范围的制约。
* 除此之外,没有其他制约条件。
* 但是,在实际问题中,我们往往需要给属性赋值加入额外的限制条件。
* 这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。
* (比如:setLegs())
*
* 同时,我们需要避免用户再使用“对象.属性”的方式对属性进行赋值。则需要将属性声明为私有的(private)
*
* ----->此时,针对于属性就体现了封装性。
*
* 二、封装性的体现:
* 我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置此属性的值。
* (只是封装性本身之一,不等同于封装性)
* 拓展:
* 封装性的体现:
* 1、如上
* 2、不对外暴露的私有的方法
* 3、单例模式
* ... ...
*
* 三、封装性的体现,需要权限修饰符来配合。
* 1、Java规定的4种权限:(从小到大排列)
* private
* 缺省(default)[什么都没写!!!]
* protected
* public
*
* 2、4种权限可以用来修饰类及类的内部结构:
* 属性
* 方法
* 构造器
* 内部类
* 3、具体的,4种权限都可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
* 修饰类的话,只能使用:
* 缺省、public
*
*/
public class AnimalTest {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "大黄";
//a.age = 1;
a.setLegs(6);
//a.legs = 3;
//The field Animal.legs is not visible不可见
//对这个属性,封装(隐藏)了
System.out.println(a.name);
}
}
class Animal{
String name;
private int age;
private int legs;
public void setLegs(int l) {
if(l >= 0 && l%2 == 0) {
legs = l;
}else {
legs = 0;
//抛出一个异常(暂时没讲)
}
}
public int getLegs() {
return legs;
}
public void eat() {
System.out.println("进食");
}
//提供关于属性age的get和set方法
public int getAge(){
return age;
}
public void setAge(int a) {
age = a;
}
}
补充:四种访问权限修饰符
Java权限修饰符public、protected、private置于类的成员定义前,用来限定对象对该类成员的访问权限
修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
---|---|---|---|---|
private | yes | |||
(缺省) | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
对于class的权限修饰只可以用public和default(缺省)
- public类可以在任意地方被访问
- default类只可以被同一个包内部的类访问。
/*
* 三、封装性的体现,需要权限修饰符来配合。
* 1、Java规定的4种权限:(从小到大排列)
* private
* 缺省(default)[什么都没写!!!]
* protected
* public
*
* 2、4种权限可以用来修饰类及类的内部结构:
* 属性
* 方法
* 构造器
* 内部类
* 3、具体的,4种权限都可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
* 修饰类的话,只能使用:
* 缺省、public
*
*/
7.4、类的成员之三:构造器(或构造方法)
构造器的特征:
- 它具有与类相同的名称
- 它不声明返回值类型。(与声明为void不同)
- 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
构造器的作用:
- 如:
- Order o = new Order(); Person p = new Person(“Peter”,15);
package com.test.dm01;
/*
* 类的结构之三:构造器(或构造方法、constructor)的使用
* construct:
* 建设、建造
* constructor:
* 建设者
*
* 一、构造器的作用:
* 1、创建对象
* 2、初始化对象的信息(给对象进行初始化)
* 二、说明:
* 1、如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
* 2、定义构造器的格式:
* 权限修饰符 类名(形参列表){}
* 3、一个类中定义的多个构造器,彼此构成重载
* 4、一旦我们显式的定义了类的构造器之后,系统就不提供默认的空参构造器!
* 5、一个类中,至少会有一个构造器。
*/
public class PersonTest {
//创建类的对象: new + 构造器
public static void main(String[] args) {
Person p = new Person("Tom");
System.out.println(p.name);
p.eat();
}
}
class Person {
//属性
String name;
int age;
//构造器
public Person() {
System.out.println("Person()...");
}
public Person(String n) {
name = n;
}
public Person(String n,int a) {
name = n;
age = a;
}
//方法
public void eat() {
System.out.println("人吃饭");
}
public void study() {
System.out.println("人可以学习");
}
}
7.5、总结: 属性赋值过程
赋值的先后顺序:
-
赋值的位置:
- 默认初始化
- 显式初始化
- 构造器中初始化
- 通过“对象.属性” 或 “对象.方法”的方式赋值
-
赋值的先后顺序:
- ①—②---③—④
package com.test.dm01;
public class UserTest {
/*
* 总结:属性赋值的先后顺序
*
* ① 默认初始化值(例如int age)
* ② 显式初始化(例如int age = 1)
* ③ 构造器中初始化(赋值)
*
*
*
* ④ 通过"对象.方法"或者"对象.属性"的方式,赋值
*
*
*
* 以上操作的先后顺序:
* ①---②---③---④
*
*
*/
public static void main(String[] args) {
User u = new User();
System.out.println(u.age);
User u1 = new User(2);
u1.setAge(3);
System.out.println(u1.age);
}
}
class User{
String name;
int age=1;
public User() {
}
public User(int a) {
age = a;
}
public void setAge(int a) {
age = a;
}
}
7.6、JavaBean
JavaBean是一种Java语言写成的可重用组件。
所谓JavaBean,是指符合如下标准的Java类:
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
用户可以使用JavaBean将功能、处理、值、数据库访问和其它任何可以用Java代码创造的对象进行打包,并且其它的开发者可以通过内部的JSP页面、Servlet、其它JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。
alt + shift + s 选择自动生成get set
7.7、拓展:UML类图
7.8、关键字:this的使用
this是什么?
在Java中,this关键字比较难理解,它的作用和其词义很接近。
- 它在方法内部使用,即这个方法所属对象的引用:
- 它在构造器内部使用,表示该构造器正在初始化的对象。
this表示当前对象,可以调用类的属性、方法和构造器
什么时候使用this关键字?
-
当在方法内需要用到调用该方法的对象时,就用this.
具体的: 我们可以用this来区分局部变量和属性。
3W: what? why? how?
package com.test.dm02;
/*
* this关键字的使用:
* 1、this可以用来修饰、调用:
* 属性、方法、构造器
*
* 2、this修饰属性和方法:
* this理解为: 当前对象 或当前正在创建的对象
*
* 2.1 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,
* 通常情况下,我们都选择省略"this.".特殊情况下,如果方法的形参和类的属性同名时,我们必须显式
* 的使用"this.变量"的方式,表明此变量是属性,而非形参。
*
*
* 2.2 在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正在创建的对象属性或方法。但是,
* 通常情况下,我们都选择省略"this.".特殊情况下,如果方法的形参和类的属性同名时,我们必须显式
* 的使用"this.变量"的方式,表明此变量是属性,而非形参。
*
*
* 3、this调用构造器
* ① 我们在类的构造器中,可以显式的使用“this(形参列表)”方式,调用本类中指定的类的其它构造器。
* ② 构造器中不能通过“this(形参列表)”方式调用自己。
* ③ 如果一个类中有n个构造器,则最多有n - 1个构造器中使用了“this(形参列表)”
* ④ 规定:“this(形参列表)” 必须声明在当前构造器的首行
* ⑤ 构造器内部,最多只能声明一个“this(形参列表)” ,用来调用其它的构造器
*/
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
}
}
class Person{
private String name;
private int age;
public Person() {
this.eat();
}
public Person(String name) {
this();
this.name = name;
}
public Person(int age) {
this();
}
public Person(String name,int age) {
this(age);
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
//this可理解为当前对象
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
}
}
7.9、关键字: package、import的使用
- 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)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI) B/S C/S
/*
* 一、package关键字的使用
* 1、为了更好的实现项目中类的管理,提供包的概念
* 2、使用package声明类或接口所属的包,声明在源文件的首行
* 3、包,属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”
* 4、每“.”一次,就代表一层文件目录。
*
* 补充:
* 同一个包下,不能命名同名的接口、类
* 不同的包下,可以命名同名的接口、类
*/
package com.test.dm02;
import java.util.Arrays;
import java.util.HashMap;
import static java.lang.System.*;
public class PackageImportTest {
/*
* 一、package关键字的使用
* 1、为了更好的实现项目中类的管理,提供包的概念
* 2、使用package声明类或接口所属的包,声明在源文件的首行
* 3、包,属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”
* 4、每“.”一次,就代表一层文件目录。
*
* 补充:
* 同一个包下,不能命名同名的接口、类
* 不同的包下,可以命名同名的接口、类
*
*
* 二、import关键字的使用
* import导入
* 1、在源文件中显式的使用import结构导入指定包下的类、接口
* 2、声明在包的声明和类的声明之间
* 3、如果需要导入多个结构,则并列写出即可。
* 4、可以使用“xxx.*”的方式表示可以导入xxx包下的所有结构。
* 5、如果使用的类或接口是java.lang包下定义的,则可以省略import结构
* 6、如果使用的类或接口是本包下定义的,则可以省略import结构
* 7、如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示。
* com.test.dm02.UserTest u = new com.test.dm02.UserTest();
* 8、如果使用“xxx.*”方式表面可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
*
* 9、import static:导入指定类或接口中的静态[结构]!!!: 属性或方法。
* import static java.lang.System.*;
*
*
*/
public static void main(String[] args) {
String info = Arrays.toString(new int[] {1,2,3});
HashMap h = new HashMap();
com.test.dm02.UserTest u = new com.test.dm02.UserTest();
}
}
7.10、MVC设计模式
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
7.11、Eclipse中的快捷键
Eclipse中的快捷键
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)
Ctrl+D: 删除当前行
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)
Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+← 前一个编辑的页面
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性
Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)
Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)
Ctrl+M 最大化当前的Edit或View (再按则反之)
Ctrl+/ 注释当前行,再按则取消注释
Ctrl+O 快速显示 OutLine
Ctrl+T 快速显示当前类的继承结构
Ctrl+W 关闭当前Editer
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)
Ctrl+/(小键盘) 折叠当前类中的所有代码
Ctrl+×(小键盘) 展开当前类中的所有代码
Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)
Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)
Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)
Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)
Ctrl+Shift+F4 关闭所有打开的Editer
Ctrl+Shift+X 把当前选中的文本全部变味小写
Ctrl+Shift+Y 把当前选中的文本全部变为小写
Ctrl+Shift+F 格式化当前代码
Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)
下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)
Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)
Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)
Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)
Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)
Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)
Alt+Shift+I 合并变量(可能这样说有点不妥Inline)
Alt+Shift+V 移动函数和变量(不怎么常用)
Alt+Shift+Z 重构的后悔药(Undo)
编辑
作用域 功能 快捷键
全局 查找并替换 Ctrl+F
文本编辑器 查找上一个 Ctrl+Shift+K
文本编辑器 查找下一个 Ctrl+K
全局 撤销 Ctrl+Z
全局 复制 Ctrl+C
全局 恢复上一个选择 Alt+Shift+↓
全局 剪切 Ctrl+X
全局 快速修正 Ctrl1+1
全局 内容辅助 Alt+/
全局 全部选中 Ctrl+A
全局 删除 Delete
全局 上下文信息 Alt+?
Alt+Shift+?
Ctrl+Shift+Space
Java编辑器 显示工具提示描述 F2
Java编辑器 选择封装元素 Alt+Shift+↑
Java编辑器 选择上一个元素 Alt+Shift+←
Java编辑器 选择下一个元素 Alt+Shift+→
文本编辑器 增量查找 Ctrl+J
文本编辑器 增量逆向查找 Ctrl+Shift+J
全局 粘贴 Ctrl+V
全局 重做 Ctrl+Y
查看
作用域 功能 快捷键
全局 放大 Ctrl+=
全局 缩小 Ctrl±
窗口
作用域 功能 快捷键
全局 激活编辑器 F12
全局 切换编辑器 Ctrl+Shift+W
全局 上一个编辑器 Ctrl+Shift+F6
全局 上一个视图 Ctrl+Shift+F7
全局 上一个透视图 Ctrl+Shift+F8
全局 下一个编辑器 Ctrl+F6
全局 下一个视图 Ctrl+F7
全局 下一个透视图 Ctrl+F8
文本编辑器 显示标尺上下文菜单 Ctrl+W
全局 显示视图菜单 Ctrl+F10
全局 显示系统菜单 Alt±
导航
作用域 功能 快捷键
Java编辑器 打开结构 Ctrl+F3
全局 打开类型 Ctrl+Shift+T
全局 打开类型层次结构 F4
全局 打开声明 F3
全局 打开外部javadoc Shift+F2
全局 打开资源 Ctrl+Shift+R
全局 后退历史记录 Alt+←
全局 前进历史记录 Alt+→
全局 上一个 Ctrl+,
全局 下一个 Ctrl+.
Java编辑器 显示大纲 Ctrl+O
全局 在层次结构中打开类型 Ctrl+Shift+H
全局 转至匹配的括号 Ctrl+Shift+P
全局 转至上一个编辑位置 Ctrl+Q
Java编辑器 转至上一个成员 Ctrl+Shift+↑
Java编辑器 转至下一个成员 Ctrl+Shift+↓
文本编辑器 转至行 Ctrl+L
搜索
作用域 功能 快捷键
全局 出现在文件中 Ctrl+Shift+U
全局 打开搜索对话框 Ctrl+H
全局 工作区中的声明 Ctrl+G
全局 工作区中的引用 Ctrl+Shift+G
文本编辑
作用域 功能 快捷键
文本编辑器 改写切换 Insert
文本编辑器 上滚行 Ctrl+↑
文本编辑器 下滚行 Ctrl+↓
文件
作用域 功能 快捷键
全局 保存 Ctrl+X
Ctrl+S
全局 打印 Ctrl+P
全局 关闭 Ctrl+F4
全局 全部保存 Ctrl+Shift+S
全局 全部关闭 Ctrl+Shift+F4
全局 属性 Alt+Enter
全局 新建 Ctrl+N
项目
作用域 功能 快捷键
全局 全部构建 Ctrl+B
源代码
作用域 功能 快捷键
Java编辑器 格式化 Ctrl+Shift+F
Java编辑器 取消注释 Ctrl+\
Java编辑器 注释 Ctrl+/
Java编辑器 添加导入 Ctrl+Shift+M
Java编辑器 组织导入 Ctrl+Shift+O
Java编辑器 使用try/catch块来包围 未设置,太常用了,所以在这里列出,建议自己设置。
也可以使用Ctrl+1自动修正。
运行
作用域 功能 快捷键
全局 单步返回 F7
全局 单步跳过 F6
全局 单步跳入 F5
全局 单步跳入选择 Ctrl+F5
全局 调试上次启动 F11
全局 继续 F8
全局 使用过滤器单步执行 Shift+F5
全局 添加/去除断点 Ctrl+Shift+B
全局 显示 Ctrl+D
全局 运行上次启动 Ctrl+F11
全局 运行至行 Ctrl+R
全局 执行 Ctrl+U
重构
作用域 功能 快捷键
全局 撤销重构 Alt+Shift+Z
全局 抽取方法 Alt+Shift+M
全局 抽取局部变量 Alt+Shift+L
全局 内联 Alt+Shift+I
全局 移动 Alt+Shift+V
全局 重命名 Alt+Shift+R
全局 重做 Alt+Shift+Y
做 java 开发的,经常会用 Eclipse 或者 MyEclise 集成开发环境,一些实用的 Eclipse 快捷键和使用技巧,可以在平常开发中节约出很多时间提高工作效率,下面我就结合自己开发中的使用和大家分享一下 Eclipse 中常用到的快捷键和技巧。
alt+? 或 alt+/:自动补全代码或者提示代码
这个是我最得意的快捷键组合了,尤其是当输入 syso 几个字符之后,2 个手指轻松按下这 2 个键的时候,自动就补全 System.out.println(); 了,而且 eclipse 默认是出现 . 进行方法提示,如果中间提示断了想再看的话还得重新在对应类或者变量的前边输入 . 才可以再看到提示,不过如果这 2 个键结合是使用同样可以起到提示的作用,你可以试一试,而且如果输入 for 后,上边如果有需要遍历的局部变量的话,会弹出选择用 for each 遍历还是 for(int;😉 还是 while() 然后自动生成代码。
ctrl+o:快速outline视图
如果想要查看当前类的方法或某个特定方法,但又不想把代码拉上拉下,也不想使用查找功能的话,就用 ctrl+o,尤其是直接打开或者跟踪到一个方法非常多的类的时候,这个就就非常有用,直接看出有那些方法及成员变量,它可以列出当前类中的所有方法及属性,你只需输入你想要查询的方法名,点击 enter 就能够直接跳转至你想去的位置。
ctrl+shift+r:打开资源列表
这可能是所有快捷键组合中最省时间的了,也是我经常用到的,尤其是根据名字直接在项目或者工作空间里找某个文件,这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或 mask 名中的前几个字母,比如 applic*.xml。美中不足的是这组快捷键并非在所有视图下都能用。
ctrl+shift+f:格式化代码
默认 80 个字符就换行,这个可以设置的。也可以根据代码风格设定重新格式化代码,我 们的团队有统一的代码格式,我们把它放在我们的 wiki 上。要这么做,我们打开 Eclipse,选择 Window Style,然后设置 Code Formatter,Code Style 和 Organize Imports。利用导出(Export)功能来生成配置文件。我们把这些配置文件放在 wiki 上,然后团队里的每个人都导入到自己的 Eclipse 中。
ctrl+e:快速转换编辑器
这组快捷键将帮助你在打开的编辑器之间浏览,尤是在很多文件打开的状态下,ctrl+e 会更加有效率,非常有帮助。
ctrl+page down 或 ctrl+page up: 选项卡之间快速切换
可以浏览前后的选项卡,如果使用熟练的话,各个页面切换会非常的快,感觉很不错。
shift+enter 及 ctrl+shift+enter: 在当前行上或者下边创建空白。
Shift+enter 在当前行之下创建一个空白行,与光标是否在行末无关。Ctrl+shift+enter 则在当前行之前插入空白行。这 2 个快捷键也是非常有帮助的,刚开始可能你不习惯,但用上多次之后,你会感觉很方便,反正我是这样的。
Alt+方向键上下:上下行交换内容或把当前行内容把上或下移动
这也是个节省时间的法宝。这个组合将当前行的内容往上或下移动。在 try/catch 部分,这个快捷方式尤其好使。
Control+Alt+方向上下键:复制高亮显示的一行或多行
这个也是非常有用的快捷键,能非常方便复制当前代码到上一行或者下一行,我也经常用到。
ctrl+m:当前编辑页面窗口最大化
大显示屏幕能够提高工作效率是大家都知道的。Ctrl+m 是编辑器窗口最大化的快捷键,再次按下就恢复正常窗口。
ctrl+/:自动注释当前行或者选择的多行
自动注释掉当前行或者多行代码,用 // 注释,用 *ctrl+* 可以取消注释。
ctrl+shift+/:自动注释掉选择的代码块
这个注意是用 /* */ 注释的(如果是编程语言代码),开发中也是非常有用的,html,css 等也可以用这个注释,生成对应的注释标签,用 *ctrl+shift+* 可以取消注释。
ctrl+d:删除当前行
删除当前行,这个很有用,我也是经常用的,尤其是在调试,删除当前错误,结合 ctrl+z 编辑撤销的快捷键,运用自如。
ctrl+shift+x 和 ctrl+shift+y :英文字母大小写的转换
这个快捷键常用语 SQL 语句的编写中,我也是经常用的,建议大家 SQL 语句中的关键字都用大写,尽管数据库大小写不区分,但这样有利于他人和自己阅读尤其是 SQL 语句非常长的情况下,而且这样看着也很规范。
ctrl+shift+o:自动引入包和删除无用包
这个快捷键也非常方便,当我们使用一个其他包中的类时,如果未引入对应的包或者类,就会出现红色波浪线的提示,此时我们可以按下这个快捷键,红色提示自动消失恢复正常,如果有多个包含有相同的这个类,那么会提示让你选择,如果有没用到的包而引入的情况,通常代码复制来复制去造成的较多,也可以用这个键快速去除。
锁定命令行窗口:在命令行视图中(Window -> Show View ->Other -> Basic -> Console),试试看用滚动锁定按钮来锁定控制台输出不要滚屏。
使用 Ant 视图: 在我的 Java 或 Debug 模式下,我喜欢显示出 Ant 视图,这样我就可以迅速的运行 Ant 任务。通过 Window Ant 可以找到该视图。把 Ant 视图放在屏幕的一角, 通过"添加编译文件(Add -> Other-> Show View -> Buildfiles)"按钮来添加build.xml文件。在3.1版本中,甚至支持Ant调试脚本语言。
自动遍历一个集合:for + Control-Space: 如果你还不知道,那么你应该记住Control-Space是自动完成功能。在Eclipse中,你还可以自动完成结构。在一个数组或集合范围内,试试看 输入"for"然后按下Control-Space键。Eclipse会问你你想要遍历哪一个集合然后自动完成循环代码。
使用分级布局: 在包浏览视图(Package Explorer view)中默认的布局(扁平式)方式让我困惑,它把包的全名显示在导航树(navigation tree)中。我更喜欢我源码的包和文件系统视图,在Eclipse中叫做分级布局(Hierarchical Layout)。要切换到这种模式,点击包浏览视图中向下的按钮,选择布局(Layout),然后选择分级(Hierarchial)。
一次显示多个文件:你可以一次浏览多个文件。把不在激活状态的编辑窗口拖到激活窗口的底部或侧边的滚动条上,就可以打开该编辑窗口。这是我能描述该窍门的最好方式了。
同时打开两个Eclipse: 要将改动从一个CVS分支上合并到另外一个上,我喜欢通过同时打开两个工作目录(Workspace)不同Eclipse来实现。这样我可以通过比较 CVS上的最新版本看到所有的变化(右键单击工程,然后选择Compare Lastest from HEAD)然后把每一个变化都合并到另外一个CVS分支上。启动多个Eclipse的最简单的方法是利用Eclipseàwith Launcher。
Implementors插件:安装一个能够跳到一个接口的实现的插件。如果你是个dependency injection 粉丝,或者正在基于编写优良的接口工作,那么你需要一个这样的插件来加速代码导航。 你可以在SourceForge找到这个插件。
自动生成getter和setter方法:在对应的POJO中,右击空白处,选择【Source】,再选择【Generate Getters and Setters】,然后选择自己对哪些属性生成这样的方法,点击【确定】就OK了,尤其是成员变量非常多的情况下,很节省时间。
附上Eclipse快捷键大全:
- Ctrl+1: 快速修复(最经典的快捷键,就不用多说了)
- Ctrl+D: 删除当前行
- Ctrl+Alt+↓: 复制当前行到下一行(复制增加)
- Ctrl+Alt+↑: 复制当前行到上一行(复制增加)
- Alt+↓: 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
- Alt+↑: 当前行和上面一行交互位置(同上)
- Alt+←: 前一个编辑的页面
- Alt+→: 下一个编辑的页面(当然是针对上面那条来说了)
- Alt+Enter: 显示当前选择资源(工程,or 文件 or文件)的属性
- Shift+Enter: 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
- Shift+Ctrl+Enter: 在当前行插入空行(原理同上条)
- Ctrl+Q: 定位到最后编辑的地方
- Ctrl+L: 定位在某行 (对于程序超过100的人就有福音了)
- Ctrl+M: 最大化当前的Edit或View (再按则反之)
- Ctrl+/: 注释当前行,再按则取消注释
- Ctrl+O: 快速显示 OutLine
- Ctrl+T: 快速显示当前类的继承结构
- Ctrl+W: 关闭当前Editer
- Ctrl+K: 参照选中的Word快速定位到下一个
- Ctrl+E: 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)
- Ctrl+/(小键盘): 折叠当前类中的所有代码
- Ctrl+×(小键盘): 展开当前类中的所有代码
- Ctrl+Space: 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)
- Ctrl+Shift+E: 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)
- Ctrl+J: 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)
- Ctrl+Shift+J: 反向增量查找(和上条相同,只不过是从后往前查)
- Ctrl+Shift+F4: 关闭所有打开的Editer
- Ctrl+Shift+X: 把当前选中的文本全部变味小写
- Ctrl+Shift+Y: 把当前选中的文本全部变为小写
- Ctrl+Shift+F: 格式化当前代码
- Ctrl+Shift+P: 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)
下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)
- Alt+Shift+R: 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)
- Alt+Shift+M: 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)
- Alt+Shift+C: 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)
- Alt+Shift+L: 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)
- Alt+Shift+F: 把Class中的local变量变为field变量 (比较实用的功能)
- Alt+Shift+I: 合并变量(可能这样说有点不妥Inline)
- Alt+Shift+V: 移动函数和变量(不怎么常用)
- Alt+Shift+Z: 重构的后悔药(Undo)