属性
对应类中的成员变量
属性和局部变量的对比:
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或(’\u000’)
布尔型(boolean)//(false)
引用数据类型(类,数组,接口)//null
局部变量:没有默认初始化值,意味着,再调用局部变量之前一定要显示赋值
2.4在内存中加载的位置
属性:加载到堆空间中 (非static)
局部变量:加载到栈空间
方法
方法:描述类应具有的功能
比如:Math类,sqrt()\random()…
Scanner类:nextXxx)()…
Array类:sort()\binarySerch()\toString\equals()…
方法的声明
权限修饰符 返回值类型 方法名(形参列表){
方法体;
}
方法的重载
1,在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或参数类型不同即可
“两同一不同”:同一个类,相同方法名
参数列表不同,参数个数不同,参数类型不同
2,判断是否重载
跟权限修饰符,返回值类型,形参变量名,方法体都没关系
3,在通过对象调用方法时,如何确定某一个指定的方法:
方法名和参数列表
方法的重写
1,重写,子类继承父类以后,可以对父类中同名参数的方法,进行覆盖操作
2,应用(where):重写以后,当创建子类对象以后,通过子类对象调用父类中的同名参数的方法时,实际执行的是子类重写父类的方法
3,重写的规定:
方法的声明:权限修饰符 返回值类型 方法名(形参列表)throws 异常的类型{
//方法体
}
约定俗称:子类中的: 叫重写的方法 父类中的: 叫被重写的方法
①子类重写的方法的*方法名和形参列表*与父类中被重写的方法的*方法名和形参列表*相同
②子类重写的方法的权限修饰符不小于父类中被重写的父类中被重写的权限修饰符
>特殊情况:子类不能重写父类中声明为**private**权限的方法
4,返回值类型:
①父类中被重写的方法的返回值类型是void,则子类中重写的方法的返回值类型只能是void
②父类中被重写的方法的返回值类型A类型(引用数据类型),则子类中重写的方法的返回值类型可以是A类或A的子类
③父类中被重写的方法的返回值类型是基本数据类型(如:double),则子类中重写的方法的返回值类型必须是相同的
④(异常处理时讲)子类重写的方法抛出异常类型不大于父类被重写的方法抛出的异常类型
可变个数形参的方法
1,可变个数形参的格式:数据类型.....变量名
如:public void show (String .....strs){
}
2,当调用可变个数形参的方法时,传入的参数个数可以是0个,1个,2个
3,可变个数形参的方法与本类中的方法名相同,形参不同的方法之间构成重载
4,可变个数的形参的方法与本类中的方法名相同,形参类型也相同的数组之间不能构成重载,换句话说,二者不能共存
5,可变个数形参在方法形参中,必须声明在末尾
*2.6可变个数形参在方法的形参中,最多只能声明一个可变形参
方法参数的值传递机制
变量的赋值:
如果变量是基本数据类型,此时赋值的是变量所保存的数据值
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值
*.针对基本数据类型的值传递机制:
1, 方法形参的传递机制:值传递
2,形参:方法定义时,声明的小括号内的参数
实参:方法调用时,实际传给形参的数据
3,值传递机制:
3.1,如果参数是基本数据类型,此时实参赋给形参的是实参真实的数据值
3.2,如果参数是引用数据类型,此时实参赋给形参的是实参储存的地址值(含变量数据类型)
递归方法
一个方法体内调用它自身
1,方法的递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无需循环控制
2,递归一定要向已知方法递归,否则这种递归就变成了无穷递归,类似于死循环
3,递归方法应用举例:
已知有一个数列:f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值
package com.mistart.java;
public class RecursionTest {
public static void main(String[] args) {
RecursionTest test = new RecursionTest();
int value = test.f(10);
System.out.println(value);
}
public int f(int n) {
if(n0) {
return 1;
}else if(n1){
return 4;
}else {
return 2*f(n-1)+f(n-2);
}
}
}
方法重载与重写的区别
1,从二者的定义细节:
>重载:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或参数类型不同即可
>重写:子类继承父类以后,可以对父类中同名参数的方法,进行覆盖操作
2, 从编译和运行的角度看:
重载,是指允许存在多个同名方法,而这些方法的参数不同,编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法,他们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载符类的同名不同参数的方法
所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”
而对于多态,只有等到方法调用的那一刻,编译器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”
3,另外:重载:不表现为多态性,而重写:表现为多态性
构造器又称构造方法
1,任何一个类都有构造器
2,创建类的对象:new+构造器:
Person p = new Person();
3,构造器与类同名
4,构造器的作用:①创建对象②初始化对象属性(对属性直接赋值)
5,说明:
①如果没有显示的定义类的构造器的话,则系统默人提供一个空参的构造器
②定义构造器的格式:权限修饰符 类名(形参列表){}
③一个类中定 义的多个构造器,彼此构成重载
④一旦我们显示的定义了类的构造器之后,系统就不在提供默认的空参构造器
⑤一个类中,至少会有一个构造器
6,构造器与方法不一样,功能和结构不一样
7,构造器特点:
①它具有与类相同的名称
②它不能声明返回值类型(与声明为void不同)
③不能被static,final,synchronized,abstract,native修饰,不能有return语句返回值
代码块
1,代码块的作用:
通常用来初始化类或者对象
格式:两个大括号,
2,修饰代码块:
只能用Static,第一个大括号前面加
3,分类: 静态代码块 vs 非静态代码块
静态代码块:
①内部可以有输出语句
②随着类的加载而执行的,内部的代码直接被执行,而且只执行一次
如:String desc = person.desc;(desc为静态方法)
③作用:初始化类的信息
④可以定义多个静态代码块,按声明的先后顺序去执行
⑤静态代码块的执行优先于非静态代码块执行
⑥静态代码块内只能调用静态的属性,静态的方法,不能调用非静态结构
非静态代码块:
①内部可以有输出语句
②随着对象的创建而执行的,每创建一个对象,就执行一个非静态代码块
如:Person p1 = new Person();
③作用:可以在创建对象时,对对象的属性等进行初始化
④可以定义多非个静态代码块,按声明的先后顺序去执行
⑤非静态代码块内能调用静态的属性,静态的方法,或调用非静态的属性,非静态的方法(此时调用非静态结构时不需要new对象,因为它是随着对象创建而被执行的)
4,对属性赋值的操作:
①默认初始化
②显示初始化
③构造器中初始化
④有了对象以后通过独对象.属性,或对象.方法调用
⑤代码块
**属性赋值的先后顺序:① - ② /⑤ - ③ - ④
②和⑤谁先写谁先执行
5,代码块运行实例:
package com.milostart.exer1;
//由父及子,静态先行
public class LeafTest {
public static void main(String[] args) {
new Leaf();
System.out.println("*********************");
new Leaf();
}
}
class Root {
static {
System.out.println(“Root的静态初始化块”);
}
{
System.out.println(“Root的普通初始化模块”);
}
public Root() {
System.out.println("Root的无参数构造器");
}
}
class Mid extends Root {
static {
System.out.println(“Mid的静态初始化块”);
}
{
System.out.println(“Mid的普通初始化模块”);
}
public Mid() {
System.out.println("Mid的无参数构造器");
}
public Mid(String msg) {
// 通过this调用同一类中的重载构造器
this();
System.out.println("Leaf的静态初始化模块");
}
}
class Leaf extends Mid {
static {
System.out.println(“Leaf的静态初始化块”);
}
{
System.out.println(“Leaf的普通初始化模块”);
}
public Leaf() {
// 通过super调用父类中有一个字符串参数的构造器
super();
System.out.println("Leaf的无参数构造器");
}
}
运行结果:
内部类
1,Java中允许将一个类A声明在另一个类B中,则A就是内部类,类B为外部类
2,分类:成员内部类 vs 局部内部类(方法内,代码块内,构造器内)
3,成员内部类:
一方面,作为外部类成员:
①可以调用外部类的结构
②可以被static修饰
③可以被四种权限修饰符修饰,外部类只能两个
另一方面,作为一个类:
①类可以定义属性,方法,构造器等
②可以被final修饰,表示此类不能被继承,言外之意,不使用final,可以被继承
③可以被abstract修饰
注:this为调方法的对象(即为调当前类里面的方法)
4,如何实例化成员内部类:
//创建Dog实例(静态成员内部类)
例如:Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(非静态的成员内部类)
例如:Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
5,如何去在成员内部类中去区分调用外部类的结构:
System.out.println(name);//方法形参
System.out.println(this.name);//内部类属性
System.out.println(Person.this.name);//外部内属性
6,开发的局部内部类的使用:
方法体内,代码块,构造器中声明的
//开发中比较少见
public void method() {
//局部内部类
class AA{
}
}
//比较常用
//返回一个实现了Comparable接口的内的对象
public Comparable getComparable() {
//创建一个实现了Coparable接口的类:局部内部类
class MyComparable implements Comparable{
public int compareTo(Object o) {
return 0;
}
}
return new MyComparable();
}
7,总结:
成员内部类和局部内部类,在编译以后,都会生成字节码文件
格式:成员内部类:外部类内部类名.class
局部内部类:外部类数字 内部类名.class