类和对象
生活中都是由许多许多的对象组成的,所有我们基于对象抽出类,那么软件中真是存在的一个个的个体,就是一个个的对象.类是对象的模型,基于类的模型创建出对象,所以对象是类的具体实例化.一个类可以创建所要的任意个对象.
类:用于封装对象的属性和行为.
类中可以包含:
对象的属性/特征(实例变量,静态变量)
静态变量和静态块
对象的行为/动作(方法)
方法(method)
方法:封装的是具体的业务逻辑功能实现
方法的重载(overload,overloading);
存在同一类当中,方法名相同,参数列表不同.(***注;不看有无返回值和返回值类型)
访问修饰词 返回值类型 方法名(参数列表(可以任意多个)) {
方法体=============具体的业务逻辑方法实现
}
方法名+参数列表称之为签名,看方法是否重载主要就是看签名是否一样.
构造方法(构造函数,构造器,构建器):
构造方法(一般称为构造函数便于与普通方法区分)的作用就是给成员变量赋初始值(创建对象使用的)
构造方法的方法名必须和类名一致,没有返回值(就连void都没有),在没写构造方法的时候系统会默认提供一个无参构造.若自己写了构造方法则系统不再默认提供,构造方法是可以重载的.
访问修饰符 类名(任意参数){
构造方法体
}
this:
this:指代当前对象,哪个对象调用方法它指的就是哪个对象 只能用在方法中,在方法中访问成员变量之前默认有个this.
this的用法:this指代的是本类(一定要区分开)
this.成员变量名========访问成员变量
this.方法名()========调用方法
this()=========调用构造方法
在参数(局部变量)和实例变量同名时this 一定不能省略,因为使用成员变量的时候默认采取就近原则,没用this其实是访问的是参数列表里面的局部变量
引用类型数组
给数组元素赋值时必须new一下,访问对象的数据必须通过数组元素打点
继承、super
作用就是实现代码重复使用.通过extends来实现继承.继承具有传递性;
超类/父类:共有的属性和行为
派生类/子类:特有的属性和行为
派生类既能访问自己的,也能访问超类,但是超类不能访问派生类
一个超类可以有多个派生类,一个派生类只能有一个超类========单继承
构造派生类之前必须先构造超类的构造方法.
在派生类的构造方法中若没有调用超类的构造方法,系统则默认调用超类的无参构造方法super()
在派生类的构造方法中若自己调用了超类的构造方法,系统则不再默认提供
超类的私有成员也会被继承,但由于私有限制访问,所以派生类不能使用超类的私有资源
继承多用于功能的修改,派生类可以在拥有超类功能的同时,进行功能上的拓展
super:指代当前对象的超类对象
super的用法:
super.成员变量名=========访问超类的成员变量
super.方法名()======================调用超类的方法
super()===========================调用超类的构造方法
我们可以把super看作是超类的对象;当超类的成员变量与子类的变量同名时,使用super指定超类的成员变量 .使用super在派生类构造方法的第一行调用超类构造方法的功能 super();–调用的是超类的无参构造 super(参数);–调用的是超类对应参数的构造方法 注意:在构造方法里,出现的调用位置必须是第一行 .
向上造型
超类的引用指向派生类的对象,能访问的变量和方法看具体是什么类型的引用 .也叫做向上类型转换或自动类型转换,即超类的引用指向派生类的对象。将派生类对象的类型转换成超类的类型。
方法的重写
在超类与派生类中,方法名相同参数列表也相同(和重载的区别).
重写方法被调用时,看对象的类型
-
继承以后,派生类就拥有了超类的功能
-
在派生类中,可以添加派生类特有的功能,也可以修改超类的原有功能
-
派生类中方法的签名与超类完全一样时,会发生覆盖/复写的现象
-
注意: 超类的私有方法不能被重写
-
重写的要求:两同两小一大 两同:方法名 参数列表 要完全一致 两小: 派生类返回值类型小于等于超类的返回值类型(***注意此处说的是继承关系,不是值大小) 派生类抛出异常小于等于超类方法抛出异常 一大:派生类方法的修饰符权限要大于等于超类被重写方法的修饰符权限
访问控制修饰符:
访问控制修饰符;封装的是具体的访问权限,其目的就是保护数据的安全,共有4种访问控制权限;
public:公开的,任何类都可以访问
protected:受保护的,只有本类、派生类、同包类可以访问
默认的:什么也不写,只有本类、同包类可以访问
private:私有的,只能本类访问
类的访问权限只能是public或默认的 类中成员的访问权限如上4种都可以
访问权限由高到低依次为:public>protected>默认的>private
static(静态)
静态变量:由static修饰,属于类,存储在方法区中,只有一份.通过类名点来访问
何时用:所有对象所共享的数据(图片、音频、视频等)
静态方法:由static修饰,属于类,存储在方法区中,只有一份,通过类名点来访问,静态方法中没有隐式this传递,不能直接访问实例成员.只有在方法的操作与对象无关时使用
静态块:由static修饰,也是属于类的,在类被加载期间自动执行,一个类只被加载一次,所以静态块只执行一次.用于加载/初始化静态资源(图片、音频、视频等)
静态变量和实例变量的区别
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。 在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
final修饰方法:
final:最终的、不可改变的
-
被final修饰的类,不能被继承
-
被final修饰的方法,不能被重写
-
被final修饰的字段是个常量,值不能被修改
static final常量
必须声明同时必须初始化,类名打点来访问,不能被改变.常量名所有字母都大写,多个单词用_分隔.编译器在编译时会将常量直接替换为具体的数,使用效率高.数据永远不变,并且经常使用得情况下用.
常量的定义形式:final 数据类型 常量名 = 值
抽象类,抽象方法
抽象类由abstract修饰,抽象类不能被实例化(new对象),建议被继承重写抽象方法,否则也声明为抽象类(一般不这么用)
抽象类的意义:实现代码复用.封装共有的属性和行为,为所有派生类提供统一的类型(向上造型),为所有派生类提供统一的入口(能点出来),派生类的行为不同,但入口是一致的,所有相当于定义了一个标准(强制派生类重写)
抽象方法:由abstract修饰,只有方法的定义,没有具体的实现(连{}都没有).使所有的派生类方法重写,(用于实现方法多态)
**注:有抽象方法的类必须是抽象类
成员内部类
成员内部类:类中套类,外面的称为外部类,里面的类称为内部类,内部类值服务于外部类,对外不可见.内部类在外部类里面创建,内部类可以之间访问外部类的成员(包括私有的)
内部类中有一个隐式的引用指向它的外部类,外部类名.this
匿名内部类
若想创建一个派生类的对象,并且该对象只被创建一次的情况下可以做成匿名内部类.匿名内部类中默认外面的变量为final
接口
接口:是一种引用数据类型,由interface来定义,只能包含常量和抽象方法,因为都是抽象的所以不能用于创建对象,实例化.接口只能被实现或者被继承(必须重写抽象方法).一个类只能单一继承,但是可以多实现,用","分隔(弥补了单一继承的单根性,实现多继承).封装部分派生类的行为.接口可以继承接口
-
通过interface关键字来定义接口
-
通过implements让子类来实现接口
-
接口中的方法全部都是抽象方法(JAVA8)
-
可以把接口理解成一个特殊的抽象类(但接口不是类!!!)
-
类描述的是一类事物的属性和方法,接口则是包含实现类要实现的方法
-
接口突破了java单继承的局限性
-
接口和类之间可以多实现,接口与接口之间可以多继承
-
接口是对外暴露的规则,是一套开发规范
-
接口提高了程序的功能拓展,降低了耦合性
多态
行为多态:通过重写方法来实现(所有的抽象方法都是多态的)
对象多态:通过向上造型来实现(每个对象都是多态的,最少也有两种形态),所有万物皆对象
内存管理
内存都是由JVM来管理的;
1.栈:
存储正在调用的方法中的局部变量(包括方法的参数),调用方法时,会在栈中为该方法分配一块对应的栈帧,栈帧中存储局部变量(包括方法的参数),方法调用结束时,栈帧被自动清除,局部变量一并被清除.调用方法时局部变量存储在栈中,方法调用结束时与栈帧一并被清除.
2.堆:
存储new出来的对象(包括实例变量)没有任何引用所指向的对象会被垃圾回收器(GC)不定时从内存中清扫,回收过程是看不到的,不一定一发现垃圾就立刻回收,通过调用System.gc()方法可以建议JVM尽快调度GC回收. 创建(new)对象时存储在堆中,对象被回收时一并被回收 内存泄漏:不再使用的对象没有被及时的回收,严重的泄漏会导致系统崩溃 建议把不再使用的对象应及时将引用设置为null
常量池:java对字符串有一个优化措施就是字符串常量池,java推荐我们使用字面量的方式来创建字符串,并且会缓存所有以字面量形式创建的字符串对象到常量池中,当使用相同字面量再创建对象时将复用常量池中的对象以减少内存开销,从而避免内存中堆积大量内容相同的字符串对象.
3.方法区:
存储.class字节码文件(包括静态变量、所有方法).
方法只有一份,通过this来区分具体的访问对象.