一、深入变量
前面已经说到变量分为成员变量、局部变量。这里将深入探究变量
1、变量的初始化:
局部变量都没有初始值,所以使用前我们自己要显示的初始化。因为系统不会对它进行初始化操作,也就是说一定要给局部变量赋值才可以使用变量。
定义局部变量后,系统并未为这个变量分配内存空间,直到程序为这个变量赋值时,系统才会为局部变量分配内存,并将初始值保存到该内存中。
局部变量不属于任何类或实例,因此它总是保存在其所在方法的栈内存中。
基本数据局部变量:直接把这个变量的值保存到该变量所对应的内存中。
引用数据局部变量:这个变量内存中存的是地址,通过该地址引用到该变量实际引用堆里的的对象。
栈内存中的变量无需系统垃圾回收,其往往随方法或代码块的运行结束而结束。
而成员变量可以不用赋值,原因是如果你不给成员变量赋值系统会自动对它进行初始化赋于默认值,定义成员变量之后系统会分配空间给它,将这个变量保存在堆中,不同类型的初始值如下:
2、变量的作用域
变量的作用域指的是变量的存在范围,只有在这个范围内,程序代码才能访问它。当一个变量被定义时,它的作用域就确定了:
A、成员变量:在类中声明,作用域是整个类。
B、局部变量:作用域是定义开始到定义所在的花括号结束。
例如:
{
int x = 12;
/*只有x有效*/
{
int q = 96;
/* x与q都有效*/
}
/*只有x有效*/
/*q已经无效了*/
}
/*x已经无效了*/
作为在作用域里定义的一个变量,它只有在那个作用域结束之前才可使用。 注意尽管在C和C++里是合法的,但在Java里不能象下面这样书写代码:
{
int x = 12;
{
int x = 96;
/* illegal */
}
}
编译器会认为变量x已被定义。这样做使程序产生了混淆。也就是说在同一个方法中不可以重复定义同一个局部变量。
C、引用类型变量:
对象的作用域Java对象不具备与主类型一样的存在时间。用new关键字创建一个Java对象的时候,它会超出作用域的范 围之外。所以假若使用下面这段代码:
{
String s = new String("a string");
} /*作用域的终点*/
那么变量s会在作用域的终点处消失。然而,s指向的String对象依然占据着内存空间。在上面这段代码 里,我们没有办法访问对象,因为指向它的唯一一个变量s已超出了作用域的边界。Java有一个特别 的“垃圾收集器”,它会查找用new创建的所有对象,并辨别其中哪些不再被引用。随后,它会自动释放由 那些闲置对象占据的内存,以便能由新对象使用。这意味着我们根本不必操心内存的回收问题。只需简单地 创建对象,一旦不再需要它们,它们就会自动离去。
3、变量的生命周期
指的是一个变量被创建并分配内存空间开始,到该变量被销毁并清除其所占内存空间的过程。不同类型的变量生命周期如下:
二、Package(创建包)、import(导入包)语句
在实际开发中,一个项目可能存在上百个甚至上千个Java文件,如果这么多Java文件全部都在一个包中,很难管理,并且也不允许存在同名的文件.
解决方案:使用package对Java的类实施分包管理.分包之后,如何去找到包中的某一个类呢?就需要使用到import去寻找包中的某一个类。
package语句必须作为文件的第一个非注释语句出现。该语句的作用是指出这个编译单元属于名为mypackage包中的一部分。或者换句话说,它表明这个编译单元内的public类名位于mypackage这个名 字的下面。如果其他人想使用这个名字,要么指出完整的名字,要么与mypackage联合使用import关键字。注意根据Java包(封装)的约定,名字内的所有字母都应小写,甚至那些中间单 词亦要如此。
现在,如果有人想使用mypackage内的任何public类,他们必须用import关键 字激活mypackage内的名字,使它们能够使用。
import mypackage.*; // . . . MyClass m = new MyClass();
另一个办法则是指定完整的名称:
mypackage.MyClass m = new mypackage.MyClass();
包名应该如何编写:
1:按照标识符的规范来书写,
2:全部使用小写字母,
3:不要使用JDK中的包名,如:java.lang/java.util.
4.如果包中第一个字母是数字_520it,我们可以使用_连接或者使用a520it.
5.但是在Android中如果包名使用_打头,则不能部署到模拟器中去,此时a520it.
6.要求独一无二
三、访问权限修饰符
访问修饰符可以修饰,成员变量,方法.
访问权限控制:
①private(类私有):本类内部可以访问,不能被之类继承,类访问权限。
② 无(包私有):本类内部可以访问,同包其他类也可以访问,能被同包的子类继承,(包访问权限)。
③protected(包和子类私有):本类内部可以访问,不同包的子类也可以访问,同包其他类也可以访问,能被子类所继承。
④public(公共):任何地方都可以访问,能继承到子类。
以后,我们把没有修饰符这种情况都统称为包私有权限。
四、this关键字
什么是this(关键字):
表示当前对象,哪个对象调用this所在的成员(方法/字段),那么this就表示哪个对象.
一般的,我们使用this主要是使用在方法中,说人话:
哪一个对象调用了this所在的方法,那么this就表示哪一个对象.
构造器中的this关键字,表示当前所创建的对象.
使用this可以解决哪些问题:
① 解决成员变量和参数之间的二义性,必须使用;
② 同类中非static方法间互调。
③ 将当前对象作为参数传递给另一个方法;
④ 当前对象作为方法的返回值(链式方法编程);
⑤ 构造器重载的互调,this([参数])必须写在构造方法第一行;
⑥static不能和this一起使用;
static成员随着字节码加载进JVM,就已经分配内存空间了,而此时并没有使用new去创建对象.
static存在的时候,对象级别数据还不存在.记住:在调用静态方法的时候,是使用类名调用的,没有对象.
五、继承
继承关系:
可以基于某个父类对对象的定义加以拓展,而产生新的子类定义,子类可以继承父类原来的某些定义,也可以增加原来父类所没有的定义,或者覆写父类中的某些特性。
在Java中子类定义时,使用“extends”关键字,并同时指定父类。
语法格式:class SubClass extends SuperClass{}
在继承(拓展)关系中,被继承的类(SuperClass)称为父类(超类、基类)。而拓展父类的类(SubClass)称为子类(派生类、拓展类),子类会自动继承父类部分的方法和字段,这里的部分和访问权限有关系。
-----------------------------------------------------------------------------------------------------------------
子类到底继承了父类的哪些成员:
1):SubClass类能继承SuperClass类中的public和protected成员(字段、方法、内部类)。
2):当SubClass和SuperClass类是位于同一包中,SubClass类会继承SuperClass类中的默认访问权限成员。
3):私有成员和构造器,绝对继承不到。
----------------------------------------------------------------------------------------------------------------
一个Java类(除了Object外)都有且只有一个直接的父类,即使一个类没有显示的继承另外一个类,那该类的直接父类默认是Object。
class Demo{}等价于class Demo extends Object{}
Java中类的继承只支持单继承,不支持多继承,但是允许多重继承,java.lang.Object是所有类(除了Object)的根类,Object要么是直接父类要么是间接父类。
方法覆盖:
方法覆写的原则(一同两小一大):复写/覆写/重写/覆盖:Override.
一同:
① 实例方法签名必须相同。(方法签名=方法名+方法的参数列表)
两小:
② 子类方法的返回值类型是父类方法的返回值类型的子类或相同类,子类方法可以返回一个更加具体的类型。
③ 子类方法声明抛出的异常应比父类方法声明抛出的异常更小或相等。
子类方法中声明抛出的异常小于或等于父类方法声明抛出异常类型;
子类方法可以同时声明抛出多个属于父类方法声明抛出异常类的子类(RuntimeException类型除外);
一大:
④ 子类方法的访问权限比父类方法访问权限更大或相等。
判断是否是覆写方法的必杀技:@Override注解:若方法是覆写方法,在方法前或上贴上该注解, 编译通过,否则,编译出错。