类
主观抽象,是对象的模板,可以实例化对象。,java类,是用来描述事物类型的。
习惯上类的定义格式
package xxx;
import xxx;
public class Xxx{
属性...; //类型 变量名
构造器(有参无参)...; //构造方法,没有返回值类型,方法名与类名相同
方法(有参无参){
方法体 //方法格式 [修饰符] 返回值类型 方法名(形参参数列表)[throws 异常]{...}
}
...;
}
获取对象的方式:
通过new(在堆空间中申请分配空间),new 类名();可以通过这种形式获得一个对象,这时的对象是垡使用的,必须把它的地址存放进一个对象变量才能够使用,如Cat cat = new Cat();
类,对象,实例三者的关系
类是对象的模板,可以实例化对象
对象是类的个体
实例是实现的对象
Object类
java类继承了Object的所有属性和方法。如toString(),hashode(),equals()。
toString()方法
经常由系统默认调用,是对当前对象的文本描述。
Date d = new Date();
System.out.println("d="+d.toString()); --此行等于下行
System.out.println("d="+d);
Object默认返回值:全限定名@hashCode,
equals()方法
默认是内存地址的比较,只不过java提供的很多类重写了此方法,也就变成了值的比较
覆盖规则
1.自反性:对于任何非空引用值x,x.equals(x)都应返回true。
2.对称性:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应该返回true。
3.传递性:对于任何非空引用值x、y、z,如果x.equals(y)返回true,并且y.equals(z)返回true,
那么x.equals(z)应返回true。
4.一致性:对于任何非空引用值x、y、z,多次调用x.equals(y)始终返回true或始终返回false,前提是对象上equals比较中所有信息没有被修改。
5.对于任何非空引用值x,x.equals(null)都应返回false。
变量
变量相当于自然语言的代词。变量让编程语言表达更方便。
在java中,每一个变量属于一种类型,声明变量时,变量所属的类型位于变量名之前,以分号结束。
如:Person p; //代表了一个人
变量的作用域:在声明的地方开始,到块结束为止;离开变量的作用域结束,变量将回收。
局部变量:不是声明在类体括号里面的变量。
1.必须要先赋值,后使用,否则通不过编译,局部变量没有默认初始化值。
2.作用范围:定义开始到定义它的代码块结束。
3.同一范围内,不允许2个局部变量命名冲突。参数传递时,简单类型进行值传递(参数进行传递时都会先去栈中生成一个副本的,使用结束后释放)。
静态变量和实例变量的区别:
1.语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
2.程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了字节码,不用创建任何实例对象,静态变量就会被分配空间,实例变量必须创建对象后才可以通过这个对象使用,静态变量则可以直接使用类名来引用。
public class Temp{
static int a; //类变量(静态变量)
public static void main(String[] args){
System.out.println(a); //打印类变量 ---0
int a = 1; //局部变量
System.out.println(a); //打印局部变量 ---1
Temp te = new Temp(); //创建实例
System.out.println(te.a); //通过实例访问实例变量 ---0
}
}
引用变量与对象的创建过程
public class BookDemo{
public static void main(String[] args){
Book book; //声明引用Book
book = new Book(); //创建对象
book.name = "盗墓笔记";
System.out.println(book.name);
book = new Book();
book.name="沙海";
System.out.println(book.name);
}
}
计算机执行java程序时会在内存中开辟一块栈内存空间,其实在程序运行期间,JVM还开辟了一个对内存空间。
栈内存空间的存储特点是"后进先出",堆内存空间的存储特点和栈不同,类似于一盘散沙,随处可以“堆放”。
程序执行过程的内存状态:
book 在栈中声明引用变量;
book = new Book(); //创建对象 book --> id = 0; name = null;
注:1.栈内存中的引用变量指向堆内存中的实例对象。
2.属性是有初始值的。
3.我们将堆内存里的东西称为“对象”,对应现实世界的事物。
book.name="盗墓笔记"; //赋值 book --> id = 0; name = "盗墓笔记";
(好习惯:一个class(类)写在一个.java文件,尽量不要把多个类写到一个.java文件中。)
book = new Book(); //创建对象 book --> id = 0; name = null;
注:1.此时堆内存中有两个对象,引用变量book指向新创建的对象。
2.原来引用的对象等待垃圾回收。book.name="沙海"; //赋值 book --> id = 0; name = "沙海";
对象实例化过程:
1.在创建类之前,检查类是否加载(将硬盘上的class文件加载到内存中),如果没有加载这个类,在这个类加载这个类之前要加载所有父类,(java运行时采用的策略:懒惰式加载(按需加载):如果第一次用到就加载, 只加载一次。通过CLASSPATH指定的路径寻找类文件(.class),加载以后是一个对象,类型是Class。)
2.在内存堆中分配对象空间。递归分配所有父类和子类属性空间。属性默认自动初始化。
3.进行属性赋值。
4.递归调用父类构造器(默认调用父类无参构造)
5.调用本类构造器。
JAVA的内存管理与分配
栈是一块java使用内存区域,使用的方式:后来者居上
对象是在堆中分配,按照类中声明属性分配空间
变量类型与分配:
1.变量分为:基本类型和引用类型。
2.基本类型变量的空间大小:就是基本类型的空间大小,值是基本类型的值。
3.引用变量的值一个对象的地址值,引用变量通过地址引用了一个堆对象。
4.引用类型变量的占用空间大小和值管理是“透明的(不可见的)”由java系统管理。构造器的作用:用来描述对象的创建过程的。
java的构造器要点:
1.java中的构造器声明在类内部。
2.方法名与类名一致的方法叫构造方法。
3.构造方法不能声明返回值类型。
4.构造方法可以包含参数,参数一般是创建对象实例必须依赖的条件(前提条件)。
java类一定有构造器,当使用new关键字时,JVM必定调用构造方法创建对象。如果类没有声明任何构造器 javac自动提供一个(无参构造)。如果提供构造器声明,javac将不再提供默认构造器。构造方法的重载:即写多个参数不一样的构造器。
构造方法重载是为了实现构造方法的重用。
注:1.方法签名 = 方法名 + 参数类型列表。
2.方法重载:方法名一样,参数不同。体现了功能的多态。重载的方法经常相互重用。
3.重载方法也可以说是方法名一样,方法签名不同的方法。方法重载方法调用原则:“就近原则”。
public class Foo{ public int add(int a,int b){ return a+b; } public long add(long a,int b){ return a+b; } public int add(int a){ return a+a; } public static void main(String[] args){ Foo f = new Foo(); System.out.println(f.add('0',1)); // add(int a,int b) } } ---------------------------------------------------- //注:java采用尽可能简单的转换原则,调用方法时将char类型转换为int,调用add(int a,int b)方法。 ---------------------------------------------------- char[] aal={'a','b','c'}; int[] bbl={1,2,3}; System.out.println(aal); //abc char数组打印的是字符串 System.out.println(bbl); //[I@2e6e1408 int数组打印的是地址 System.out.println('a'); //a 打印字符 System.out.println(2); //2 打印数字 //如上所示打印出不同结果,是因为根据参数不同,调用了System.out.println()不同的重载方法。
对象的方法:表示对象的功能,依赖于对象存在。
java中的方法:方法就是函数
1.方法的语法:(修饰词)(返回值类型)(方法名)(参数列表){ /*方法体*/ }
注:java方法必须定义返回值类型,如果没有返回值使用void定义一般方法也一样。
2.return关键字:如果有返回值定义就必须有return语句,返回和返回值类型兼容的数据。
3.局部变量:方法的参数和方法内部的变量,都是局部变量,这些变量作用域只在方法内部,在一个方法中定义的变量只能在本方法中使用。
4.形参和实参:
形参:方法的参数定义,是临时变量(是个空壳子,相当于声明变量而没有赋值)。
实参:方法调用时候实际传递的参数变量(实际的值,相当于赋值)。在null上引用属性或方法,会发生运行时异常。
Overload和Override的区别:Overload(重载),Override(重写)。
重载表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。
重写表示子类中的方法可以与父类中的某个方法的名称和参数相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,相当于重写了父类的方法。这也是面向对象编程的多态性的一种表现。子类只能比父类抛出更少的异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法访问权限只能比父类更大,不能更小。如果父类的方法是private类型,那么子类将不受限制,相当于子类多了一个全新的方法。
重载:
发生在同一个类中
相同的方法名
参数列表不同
不看返回值,如果出现了只有返回值不同的“重载”,是错的。
重写:
发生在子类与父类中
相同的方法名
相同的参数列表
返回值相同 或者 子类方法的返回值是父类方法返回值类型的子类
访问修饰符相同 或者 子类方法的修饰符范围 大于 父类
抛出的异常相同 或者 子类方法抛出的异常 小于父类
== 和 equals 的区别是什么?
== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用地址;
equals 默认情况下是引用地址比较,只是很多类重写了 equals 方法,比如 String、Integer 等把它变成了值比较。