属性
又称为成员变量,属性的声明是在类中方法外
声明
修饰符 数据类型 属性名 = 初始值; //显式初始化
修饰符 数据类型 属性名; //声明类时没有显式给属性赋初值,那么在创建对象后,属性有默认的初始值
修饰符
- 权限修饰符:private、缺省、protected、public
- 其他修饰符:static、final
封装
- 属性使用private修饰,只能在本类中直接使用,在其他类中不可见
- 提供公共的getXxx()/setXxx()
- set方法:用于为属性赋值,修改属性值
- get方法:用于获取、访问某个属性的值
属性赋值顺序
- 默认初始化
- 显式初始化/代码块赋值
- 构造器中初始化
- 通过
**对象.属性**
或**对象.方法**
的方式赋值
与局部变量的区别
- 声明位置、修饰符、内存位置、是否默认初始化
方法
基本概念
方法是类或对象行为特征的抽象,用来完成某个功能操作
修饰符 返回值类型 方法名(形参列表) 抛出的异常列 {
方法的实现
}
意义
使程序变得简短而清晰
- 有利于程序的维护
- 提高程序开发的效率
- 提高代码的重用性
注意:Java里的方法不能独立存在,所有的方法必须定义在类里
分类
按参数
无参
修饰符 返回值类型 方法名() {
方法体
}
有参
修饰符 返回值类型 方法名(形参列表) {
方法体
}
按返回值
- void类型修饰的方法——单独调用
- 有明确返回值的方法
- 单独调用,没有意义
- 输出调用,不是很好,可能需要对结果进一步操作
- 赋值调用,推荐
- 在本类中
- 变量名 = 方法名(实参列表);
- 作为另一个方法调用的实参
- 作为表达式的一部分
- 按static
- 本类中
**方法名(实参列表);**
- 在其他类中
- 方法是static修饰的
- 本类中
**类名.方法名(实参列表);**
**变量名 = 类名.方法名(实参列表);**
- 方法是非static修饰的
**对象名.方法名(实参列表);**
**变量名 = 对象名.方法名(实参列表);**
命令行参数
- public static void main(String[] args)
- 通过命令行传的参数,在args数组中
- 如果要使用命令行的参数 args[0]…
- 怎么传
- cmd: java 包.类 参数1 参数2 参数3…
- eclipse: run菜单—>run configration—>选择运行哪个main方法—>program argument
- IDEA: Edit Configurations
返回值
- 基本类型
- 类: 返回的是该类的一个对象
- 抽象类: 返回的是该抽象类的子类对象。用多态的方法
- 接口: 返回的是该接口的实现类对象。用多态的方法
- 链式编程
**对象.方法1().方法2().方法3();**
- 方法1()调用完毕后,返回一个对象;
- 方法2()调用完毕后,返回一个对象;
- 方法3()调用完毕后,可以是对象,也可以不是
注意事项
- 方法不调用不执行
- 方法之间是平级关系,不能嵌套定义
- 实参的数目、数据类型和次序必须和所调用的方法声明的形式参数列表匹配
return 语句终止方法的运行并指定要返回的数据,如果方法有明确的返回值类型,就必须有return语句返回一个值
重载
在同一个类中,方法名相同,参数列表不同,与返回值无关
参数的个数不同或参数的对应的数据类型不同
- 只有返回值不同不构成方法的重载
- 只有形参的名称不同,不构成方法的重载
作用:允许功能相似的方法重名,使方法定义和调用都简化了
调用:正常方法调用即可,传进对应的参数,编译器自动选择你指定类型参数的方法执行
可变参数
声明**数据类型... 形参名**
- 一个方法最多只能有一个可变参数
- 声明必须在方法的形参列表的最后一个
- 可变参数的数据类型可以是任意类型
数据类型[] 形参名
与可变参数不能构成重载
使用
- 在声明它的方法中,可变参数当做数组使用——形参名就是数组名
可变参数的方法调用时
基本类型做参数:将实参基本数据类型变量的“数据值”传递给形参,形参的改变不影响实参
- 引用类型做参数:将实参引用数据类型变量的“地址值”传递给形参,形参的改变影响实参
实参将值传给形参的过程,称为参数传递,实际上就是一个赋值的过程
递归
一个方法体内调用它自身
方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环
递归结构包括两个部分
- 递归头:递归的结束条件,如果没有头,将陷入死循环
- 递归体
递归的缺陷
- 递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重
- 任何能用递归解决的问题也能使用迭代解决。当递归方法可以更加自然地反映问题,并且易于理解和调试,不强调效率问题时,可以采用递归
构造器
是一个创建对象时被自动调用的特殊方法,给对象的数据进行初始化
//无参构造
修饰符 类名() {
方法体
}
//有参构造
修饰符 类名(形参列表) {
方法体
}
特点
- 构造器方法名必须与类名相同
- 构造器没有返回值类型
- 构造器可以重载
- 任何类中都有构造器,如果没有显式定义构造器,编译器将自动添加一个默认的无参构造器
- 如果显式/手动声明了任何一个构造器,编译器将不再自动添加默认的无参构造
- 不能被static、final、synchronized、abstract、native修饰,不能有return语句
- 父类的构造器不可被子类继承
作用
- 和new一起使用,创建对象
**new 构造方法();**
调用无参构造,Random rand = new Random();
**new 构造方法(实参列表);**
调用有参构造,Scanner input = new Scanner(System.in);
为属性赋值
对象创建的过程
- 构造方法是创建Java对象的重要途径,通过new关键字调用构造器时,构造器也确实返回该类的对象,但这个对象并不是完全由构造器负责创建
- 创建一个对象分为如下四步:
- 分配对象空间,并将对象成员变量默认初始化
- 显式初始化、多个初始化块依次被执行
- 执行构造方法体
- 返回对象的地址给相关的变量
JavaBean
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
代码块
用来初始化类、对象
静态代码块
static {
}
- 内部可以有输出语句
- 随着类的加载而执行,而且只执行一次
- 作用:初始化类的信息
- 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
- 静态代码块的执行要优先于非静态代码块的执行
- 静态代码块内只能调用静态的属性、静态的方法,不能调用非静态结构
非静态代码块
{
}
在类中,称为构造块
在方法中,称为普通代码块
- 内部可以有输出语句
- 构造块随着对象的创建而执行
- 每创建一个对象,就执行一次构造块
- 作用:可以在创建对象时,对对象的属性等进行初始化
- 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
- 非静态代码块内可以调用静态的属性、方法,或非静态的属性、方法
- 当多个构造器中重复的代码,可以提取到构造块中
执行特点
- 由父及子,静态先行
- 静态代码块(只执行一次)——构造块(每次创建对象)——构造器(每次创建对象)
示例
class Father {
static {
System.out.println("1");
}
{
System.out.println("2");
}
public Father() {
System.out.println("3");
}
}
public class Son extends Father {
static {
System.out.println("4");
}
{
System.out.println("5");
}
public Son() {
System.out.println("6");
}
public static void main(String[] args) { // 由父及子 静态先行
System.out.println("0");
System.out.println("************************");
new Son();
System.out.println("************************");
new Son();
System.out.println("************************");
new Father();
}
}
内部类
定义
- 把类定义在其他类的内部,这个类就被称为内部类
- 成员内部类编译会生成Outer.class和Outer$Inner.class
- 局部内部类会生成Outer.class和Outer$1Inner.class,同名内部类数字1会递增
内部类的访问规则
- 内部类可以直接访问外部类的成员包括私有
- 外部类要访问内部类的成员,必须创造对象
- 内部类和外部类没有继承关系。内部类如果想要访问外部的变量,需要创建对象,或巧用this关键字(假装这里有一个指向上边的箭头)通过外部类名限定this对象
**outer.this**
内部类的作用
- 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类
- 实现多继承
-
成员内部类
在成员位置定义的类被称为成员内部类,和成员方法、成员变量平级
修饰符 class 外部类 {
修饰符 class 内部类 {
}
}
特点
一方面,作为外部类的成员:
- 调用外部类的结构
- 可以被static修饰
- 可以被4种不同的权限修饰
另一方面,作为一个类:
在外部类的外面使用内部类
Outer.Inner inner = new Outer().new Inner();
或
Outer out = new Outer();
Outer.Inner inner = out.new Inner();
在外部类中使用内部类
- 在外部类的静态成员中,不能直接使用内部类
- 在外部类的非静态成员部分,把内部类当做普通类使用
-
静态内部类
在外部类的外面
Outer.Inner inner = new Outer.Inner();
在外部类中使用没有限制
在内部类中使用外部类的成员
只能在声明它的方法、代码块、构造器中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类
- 局部内部类可以使用外部类的成员,包括私有的
- 局部内部类可以使用外部方法的局部变量但是必须是final的,由局部内部类和局部变量的声明周期不同所致
- 不能使用public protected private static这些成员修饰符
-
匿名内部类
new 父类构造器(实参列表|实现接口) {
匿名内部类的类体部分
}
特点
- 匿名内部类必须继承父类或实现接口
- 匿名内部类只能有一个对象
- 匿名内部类对象只能使用多态形式引用
- 匿名内部类没有访问修饰符、构造器、类名
- 只有一个对象,声明匿名内部类与创建对象,同时进行
范例
public class InnerClassTest {
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
class MyComparable implements Comparable {
@Override
public int compareTo(Object o) {
return 0;
}
}
return new MyComparable();
//方式二:
return new Comparable() {
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
UML类图
- 表示public类型, - 表示private类型,# 表示protected类型
方法的写法:方法的类型(+、-) 方法名(参数名: 参数类型):返回值类型