内容:
1.内存管理
2.继承
3.super关键字
4.向上造型
一、对象内存管理:分为 堆、栈、方法区
java程序所需内存均由JVM进行管理分配
例子:java程序,内存不够
买内存条,装到电脑上----结果仍是内存不够
开发者只需关心JVM是如何管理内存的,而无需关注某种操作系统是如何管理内存的,这就保证了java程序的平台无关性
1.堆
a.new关键字所创建的对象(包括成员变量)---存储在堆中
b.成员变量的生命周期---从对象在堆中创建开始到对象从堆中被回收结束,废弃的对象被回收时,成员变量也随之被回收
c.垃圾回收机制(Java提供的自动释放内存空间的机制)---JVM自带的一个线程(自动运行着的程序),用于回收**没有任何引用所指向**的对象。
没有任何引用的对象即为垃圾,垃圾回收器(GC)会不定时清理垃圾。回收的过程是透明的,并不是一看到垃圾就马上清理
通过调用System.gc()可以建议快一些清理,但具体的实现策略取决于不同的JVM系统
java程序员不用担心内存管理,因为垃圾收集器会自动进行管理
d.Java程序的内存泄露---指不再被使用的内存没有被及时的回收,严重的内存泄露会因过多的内存占用而导致程序的崩溃。
尽量避免不必要的内存浪费。
当确定该对象不再使用时,应该及时的将其引用设置为null,以此来避免内存泄露问题
2.栈
a.用于存储正在调用的方法中的局部变量
调用方法时,在栈中为该方法分配一个叫栈帧的空间
栈帧中存储该方法的所有局部变量
方法调用结束是,栈帧被删除,局部变量一并消失
b.局部变量的生命周期
调用方法时存在栈中,方法调用完成后,其对应的栈帧将被清除,局部变量即失效。
c.成员变量与局部变量的差别
局部变量:
1).定义在方法中;
2).没有默认值,必须自行设定初始值;
3).方法被调用时,存在栈中,方法调用结束时局部变量从栈中清除;
成员变量:
1).定义在类中,方法外;
2).由系统设定默认初始值,可以不显式初始化;
3).所在类被实例化后,存在堆中,对象被回收时,成员变量失效;
3.方法区---用于存放类的各种信息(.class字节码文件(包括方法))
方法只有一份,存在方法区中:因此才有this关键字,来区分到底是哪个对象调用的方法
类在实例化对象时,多个对象会拥有各自在堆中的空间,但所有实例对象是共用在方法区中的一份方法定义的。
二、继承---继承这个过程就是泛化的过程
1.作用:避免代码重复,有利于代码的复用
2.通过extends关键字实现继承
3.父类:所有子类所共有的属性和行为(成员变量和方法)
子类:子类所特有的属性和行为
4.当子类继承父类后,子类具有:子类+父类
5.一个父类可以有多个子类
一个子类只能有一个父类---单一继承(主要是为了类层次结构清晰),主要的类类型都可以追溯到继承Object
6.具有传递性
class Aoo{
int a;
}
class Boo extends Aoo{
int b;
}
class Coo extends Boo{
int c;
}
Coo o = new Coo():
o.c=1;
o.b=2;
o.a=3;
7.java规定:a.构造子类之前必须先构造父类
b.子类的构造方法中是必须要通过super关键字来调用父类的构造方法的,这样才可以保证妥善的初始化继承自父类的成员变量
c.在子类构造方法中没有写super调用父类构造方法,这时编译器会默认添加super()来调用父类的无参构造方法,
d.若父类中又没有定义无参的构造方法,因此会发生编译错误
注:
每个类都必须含有构造方法:
若自己不写构造方法,则编译器默认提供一个无参的构造器
若自己写了构造方法,则编译器将不在默认提供
三、super关键字:指代当前对象的父类对象
用法:
1.super.成员变量名;---访问父类的成员变量 (很少用)
2.super.方法名();---调用父类的方法
3.super();---调用父类的构造器,*****super关键字必须位于子类***构造方法***的第一行*****
注:构造器重载,使用this()调用本类中另一个构造器时,this()必须放在第一行。
子类构造器执行的第一行代码使用this显式调用本类中重载的构造器,系统将根据this调用里传入的实参列表调用本类中的另一个构造器。
执行本类中另一个构造器时即会调用父类构造器。
=================================
并非一次判断得到最终结果---开关法
=================================
四、向上造型:一个子类的对象可以向上造型为父类的类型
1.父类型的引用指向子类的对象 Person p1 = new Student();
2.能点出来什么,看引用的类型:如引用的类型是父类型,而指向的是子类对象,那么这个引用不能访问子类(除重写)
回顾:
1.内存管理
a.堆:new关键字创建出来的对象(包括成员变量)
b.栈:正在调用中的方法的局部变量
c.方法区:.class字节码(包括方法)
2.继承
a.意义、作用:避免代码重复,有利于代码的复用
b.extends
c.父类/基类:共有的
子类/派生类:特有的
d.子继承父后,子具有:子+父
e.单一继承
f.传递性
g.构造子之前必须先构造父
子类若不调父类构造,则默认super()
子类若调父类构造,则不再默认提供
3.super:指代当前对象的父类对象
a.super.成员变量名 ---访问父类的成员变量
b.super.方法名() ---调用父类的方法
c.super() ---调用父类的构造器,super关键字必须位于子类构造方法的第一行
4.向上造型
a.父类型的引用指向子类的对象
b.能点出来什么,看引用的类型
正课:
1.方法的重写
2.重载与重写的区别
3.package和import
4.访问控制修饰符
5.static
6.final
一、重写
需遵守"两同两小一大"规则:
1).两同:
a.方法名相同
b.参数列表相同
2).两小:
a.子类的返回值类型小于或等于父类 ====一般写成相等的
1.返回值类型为void和8种基本类型时,子类与父类的返回值类型必须完全相同
2.返回值类型为引用类型时,子类的返回值类型小于或等于父类 ----父类大,子类小
b.子类抛出的异常小于或等于父类的
3).子类的访问权限不能比父类的更严格
子类继承父类后:
若觉得父类的方法不符合子类的要求---重写
若子类完全修改了父类的---直接重写
若子类是在父类的基础上修改---先调父类的再添加新内容
1.方法的重写:覆盖、override
1).子类可以重写(覆盖)继承自父类的方法,方法签名(方法名和参数列表)相同,但方法体不同
2).重写方法被调用时(无论是通过子类的引用调用还是通过父类的引用调用),看new关键字创建出来的对象的类型
3).父类类型引用指向子类对象,引用不能调用子类所特有的成员变量和方法。
2.重写中使用super关键字:super.方法名(); ====重写方法时可以不用放在第一行,但重写构造器时必须放在子类构造器的第一行
在子类重写的方法中,可以通过super关键字调用父类的版本。
通常用于子类的重写方法在父类方法的基础之上进行的功能扩展。
3.重写和重载的区别 -----重载看引用,重写看对象
a.重写override:发生在父子类中,方法签名(方法名和参数列表)相同,但**方法体不同**
遵循“运行期”绑定,看对象的类型调用/根据对象的类型不同而来调用不同的版本
b.重载overload:发生在同一个类中,方法名称相同,参数列表不同
遵循“编译期”绑定,看引用的类型绑定/看参数的个数及类型来绑定哪个方法
特例:class Aoo{
void show(){
}
}
class Boo extends Aoo{
void show(){//重写
方法体;
....
}
void show(String name){//重载
}
}
二、package和import
1.package:包
a.作用:避免类名的冲突
b.包名可以有层次结构
完全限定名:包名.类名
c.包名所有字母都小写
命名建议:域名反写.项目名称.模块名称.类名
cn.tedu.stumanager.course.Java
2.import:导包
a.同包中的类可以直接访问
b.不同包中的类不能直接访问,要访问有两种方式:
1).类的完全限定名 ----不建议
2).先import声明类,再直接访问 ----建议
import 包名.类名
三、访问控制修饰符
1.封装:提高数据的安全性、操作简单
数据私有化,行为公开化(成员变量private,方法public)
封装的意义:
1).降低代码出错的可能性,便于维护
2).当内部实现细节改变时,只要保证对外的功能定义不变,其他的模块不需要更改
2.访问控制修饰符
1).public ---公开的,任何类 ----使用频率高
2).protected ---受保护的,本类、子类、同包类中可以使用
3).默认的---本类、同包类中可以使用 ----java不建议使用默认的(什么都不写)
4).private ---私有的,只能在本类中使用 ----使用频率高
类只能用public和默认的去修饰(内部类除外)
类成员(成员变量和方法)的修饰以上4种修饰符都可以
public/private/protected不能用来修饰局部变量
四、static关键字
成员变量:
实例变量:没有static修饰,属于对象,存在堆中
有几个对象就有几份
通过对象.来访问
静态变量:由static修饰,属于类,存在方法区中
只有一份
1.修饰变量,叫静态变量
a.由static修饰
b.属于类,存在方法区中,只有一份
c.常常通过类名.来访问(对象.来访问也不错,但不建议)
d.何时用:所有对象的数据都一样
class student{
String name;
int age;
String address;
static String className;//因为每个学生的班级相同
}
Student stu1 = new Student();
stu1.name = "zc";
stu1.age = 28;
stu1.address = "中国";
Student.className = "JSD1603";
2.修饰方法,叫静态方法---没有this (没有static修饰,叫实例方法---有this)
a.由static修饰
b.属于类,存在方法区中,只有一份
c.常常通过类名.来访问(对象.来访问也不错,但不建议)
d.静态方法中没有隐式的this.传递
没有this就意味着没有对象
而实例成员(实例方法和实例变量)必须对象.来访问
***所以静态方法中不能直接访问实例成员*** 请注意直接2字
e.何时用:方法的操作仅与参数相关而与对象无关
静态方法:
double a = Math.random();
double b = Math.sqrt(25);
int[] a1 = Arrays.copyOf(arr,6);
Arrays.sort(arr);
class Aoo{
int a;
static int b;
void show(){
a=1;
b=2;//b是静态变量,与方法都存在方法区,所以可以访问
}
static void test(){
a=2;//编译错误,没有this就没有对象,所以不能直接访问实例成员
b=3;//b是静态变量,与方法都存在方法区,所以可以访问
}
}
3.静态块:static块,属于类的代码块。在类加载期间执行的代码块,只执行一次
1).属于类,在类加载期间自动执行
2).因类只加载一次,故静态块也只执行一次
3).常常用于加载/初始化静态资源(图片、音频、视频... *只有一份*)
class Foo{
static {
System.out.print("静态块");
}
public Foo(){
System.out.println("构造方法");
}
}
在main方法中创建对象:
//创建对象时,首先会在方法区加载Foo类
Foo o = new Foo();//输出:静态块 构造方法
Foo o1 = new Foo();//输出:构造方法
五、final关键字:不可变 ----单独使用的几率不大
1.修饰变量:变量不能被改变
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
a.修饰成员变量:
1).声明的同时初始化
2).构造方法中初始化
b.修饰局部变量:
1).用之前初始化即可
2.修饰方法:方法不能被子类重写
3.修饰类:类不能被继承
1.内存管理
2.继承
3.super关键字
4.向上造型
一、对象内存管理:分为 堆、栈、方法区
java程序所需内存均由JVM进行管理分配
例子:java程序,内存不够
买内存条,装到电脑上----结果仍是内存不够
开发者只需关心JVM是如何管理内存的,而无需关注某种操作系统是如何管理内存的,这就保证了java程序的平台无关性
1.堆
a.new关键字所创建的对象(包括成员变量)---存储在堆中
b.成员变量的生命周期---从对象在堆中创建开始到对象从堆中被回收结束,废弃的对象被回收时,成员变量也随之被回收
c.垃圾回收机制(Java提供的自动释放内存空间的机制)---JVM自带的一个线程(自动运行着的程序),用于回收**没有任何引用所指向**的对象。
没有任何引用的对象即为垃圾,垃圾回收器(GC)会不定时清理垃圾。回收的过程是透明的,并不是一看到垃圾就马上清理
通过调用System.gc()可以建议快一些清理,但具体的实现策略取决于不同的JVM系统
java程序员不用担心内存管理,因为垃圾收集器会自动进行管理
d.Java程序的内存泄露---指不再被使用的内存没有被及时的回收,严重的内存泄露会因过多的内存占用而导致程序的崩溃。
尽量避免不必要的内存浪费。
当确定该对象不再使用时,应该及时的将其引用设置为null,以此来避免内存泄露问题
2.栈
a.用于存储正在调用的方法中的局部变量
调用方法时,在栈中为该方法分配一个叫栈帧的空间
栈帧中存储该方法的所有局部变量
方法调用结束是,栈帧被删除,局部变量一并消失
b.局部变量的生命周期
调用方法时存在栈中,方法调用完成后,其对应的栈帧将被清除,局部变量即失效。
c.成员变量与局部变量的差别
局部变量:
1).定义在方法中;
2).没有默认值,必须自行设定初始值;
3).方法被调用时,存在栈中,方法调用结束时局部变量从栈中清除;
成员变量:
1).定义在类中,方法外;
2).由系统设定默认初始值,可以不显式初始化;
3).所在类被实例化后,存在堆中,对象被回收时,成员变量失效;
3.方法区---用于存放类的各种信息(.class字节码文件(包括方法))
方法只有一份,存在方法区中:因此才有this关键字,来区分到底是哪个对象调用的方法
类在实例化对象时,多个对象会拥有各自在堆中的空间,但所有实例对象是共用在方法区中的一份方法定义的。
二、继承---继承这个过程就是泛化的过程
1.作用:避免代码重复,有利于代码的复用
2.通过extends关键字实现继承
3.父类:所有子类所共有的属性和行为(成员变量和方法)
子类:子类所特有的属性和行为
4.当子类继承父类后,子类具有:子类+父类
5.一个父类可以有多个子类
一个子类只能有一个父类---单一继承(主要是为了类层次结构清晰),主要的类类型都可以追溯到继承Object
6.具有传递性
class Aoo{
int a;
}
class Boo extends Aoo{
int b;
}
class Coo extends Boo{
int c;
}
Coo o = new Coo():
o.c=1;
o.b=2;
o.a=3;
7.java规定:a.构造子类之前必须先构造父类
b.子类的构造方法中是必须要通过super关键字来调用父类的构造方法的,这样才可以保证妥善的初始化继承自父类的成员变量
c.在子类构造方法中没有写super调用父类构造方法,这时编译器会默认添加super()来调用父类的无参构造方法,
d.若父类中又没有定义无参的构造方法,因此会发生编译错误
注:
每个类都必须含有构造方法:
若自己不写构造方法,则编译器默认提供一个无参的构造器
若自己写了构造方法,则编译器将不在默认提供
三、super关键字:指代当前对象的父类对象
用法:
1.super.成员变量名;---访问父类的成员变量 (很少用)
2.super.方法名();---调用父类的方法
3.super();---调用父类的构造器,*****super关键字必须位于子类***构造方法***的第一行*****
注:构造器重载,使用this()调用本类中另一个构造器时,this()必须放在第一行。
子类构造器执行的第一行代码使用this显式调用本类中重载的构造器,系统将根据this调用里传入的实参列表调用本类中的另一个构造器。
执行本类中另一个构造器时即会调用父类构造器。
=================================
并非一次判断得到最终结果---开关法
=================================
四、向上造型:一个子类的对象可以向上造型为父类的类型
1.父类型的引用指向子类的对象 Person p1 = new Student();
2.能点出来什么,看引用的类型:如引用的类型是父类型,而指向的是子类对象,那么这个引用不能访问子类(除重写)
回顾:
1.内存管理
a.堆:new关键字创建出来的对象(包括成员变量)
b.栈:正在调用中的方法的局部变量
c.方法区:.class字节码(包括方法)
2.继承
a.意义、作用:避免代码重复,有利于代码的复用
b.extends
c.父类/基类:共有的
子类/派生类:特有的
d.子继承父后,子具有:子+父
e.单一继承
f.传递性
g.构造子之前必须先构造父
子类若不调父类构造,则默认super()
子类若调父类构造,则不再默认提供
3.super:指代当前对象的父类对象
a.super.成员变量名 ---访问父类的成员变量
b.super.方法名() ---调用父类的方法
c.super() ---调用父类的构造器,super关键字必须位于子类构造方法的第一行
4.向上造型
a.父类型的引用指向子类的对象
b.能点出来什么,看引用的类型
正课:
1.方法的重写
2.重载与重写的区别
3.package和import
4.访问控制修饰符
5.static
6.final
一、重写
需遵守"两同两小一大"规则:
1).两同:
a.方法名相同
b.参数列表相同
2).两小:
a.子类的返回值类型小于或等于父类 ====一般写成相等的
1.返回值类型为void和8种基本类型时,子类与父类的返回值类型必须完全相同
2.返回值类型为引用类型时,子类的返回值类型小于或等于父类 ----父类大,子类小
b.子类抛出的异常小于或等于父类的
3).子类的访问权限不能比父类的更严格
子类继承父类后:
若觉得父类的方法不符合子类的要求---重写
若子类完全修改了父类的---直接重写
若子类是在父类的基础上修改---先调父类的再添加新内容
1.方法的重写:覆盖、override
1).子类可以重写(覆盖)继承自父类的方法,方法签名(方法名和参数列表)相同,但方法体不同
2).重写方法被调用时(无论是通过子类的引用调用还是通过父类的引用调用),看new关键字创建出来的对象的类型
3).父类类型引用指向子类对象,引用不能调用子类所特有的成员变量和方法。
2.重写中使用super关键字:super.方法名(); ====重写方法时可以不用放在第一行,但重写构造器时必须放在子类构造器的第一行
在子类重写的方法中,可以通过super关键字调用父类的版本。
通常用于子类的重写方法在父类方法的基础之上进行的功能扩展。
3.重写和重载的区别 -----重载看引用,重写看对象
a.重写override:发生在父子类中,方法签名(方法名和参数列表)相同,但**方法体不同**
遵循“运行期”绑定,看对象的类型调用/根据对象的类型不同而来调用不同的版本
b.重载overload:发生在同一个类中,方法名称相同,参数列表不同
遵循“编译期”绑定,看引用的类型绑定/看参数的个数及类型来绑定哪个方法
特例:class Aoo{
void show(){
}
}
class Boo extends Aoo{
void show(){//重写
方法体;
....
}
void show(String name){//重载
}
}
二、package和import
1.package:包
a.作用:避免类名的冲突
b.包名可以有层次结构
完全限定名:包名.类名
c.包名所有字母都小写
命名建议:域名反写.项目名称.模块名称.类名
cn.tedu.stumanager.course.Java
2.import:导包
a.同包中的类可以直接访问
b.不同包中的类不能直接访问,要访问有两种方式:
1).类的完全限定名 ----不建议
2).先import声明类,再直接访问 ----建议
import 包名.类名
三、访问控制修饰符
1.封装:提高数据的安全性、操作简单
数据私有化,行为公开化(成员变量private,方法public)
封装的意义:
1).降低代码出错的可能性,便于维护
2).当内部实现细节改变时,只要保证对外的功能定义不变,其他的模块不需要更改
2.访问控制修饰符
1).public ---公开的,任何类 ----使用频率高
2).protected ---受保护的,本类、子类、同包类中可以使用
3).默认的---本类、同包类中可以使用 ----java不建议使用默认的(什么都不写)
4).private ---私有的,只能在本类中使用 ----使用频率高
类只能用public和默认的去修饰(内部类除外)
类成员(成员变量和方法)的修饰以上4种修饰符都可以
public/private/protected不能用来修饰局部变量
四、static关键字
成员变量:
实例变量:没有static修饰,属于对象,存在堆中
有几个对象就有几份
通过对象.来访问
静态变量:由static修饰,属于类,存在方法区中
只有一份
1.修饰变量,叫静态变量
a.由static修饰
b.属于类,存在方法区中,只有一份
c.常常通过类名.来访问(对象.来访问也不错,但不建议)
d.何时用:所有对象的数据都一样
class student{
String name;
int age;
String address;
static String className;//因为每个学生的班级相同
}
Student stu1 = new Student();
stu1.name = "zc";
stu1.age = 28;
stu1.address = "中国";
Student.className = "JSD1603";
2.修饰方法,叫静态方法---没有this (没有static修饰,叫实例方法---有this)
a.由static修饰
b.属于类,存在方法区中,只有一份
c.常常通过类名.来访问(对象.来访问也不错,但不建议)
d.静态方法中没有隐式的this.传递
没有this就意味着没有对象
而实例成员(实例方法和实例变量)必须对象.来访问
***所以静态方法中不能直接访问实例成员*** 请注意直接2字
e.何时用:方法的操作仅与参数相关而与对象无关
静态方法:
double a = Math.random();
double b = Math.sqrt(25);
int[] a1 = Arrays.copyOf(arr,6);
Arrays.sort(arr);
class Aoo{
int a;
static int b;
void show(){
a=1;
b=2;//b是静态变量,与方法都存在方法区,所以可以访问
}
static void test(){
a=2;//编译错误,没有this就没有对象,所以不能直接访问实例成员
b=3;//b是静态变量,与方法都存在方法区,所以可以访问
}
}
3.静态块:static块,属于类的代码块。在类加载期间执行的代码块,只执行一次
1).属于类,在类加载期间自动执行
2).因类只加载一次,故静态块也只执行一次
3).常常用于加载/初始化静态资源(图片、音频、视频... *只有一份*)
class Foo{
static {
System.out.print("静态块");
}
public Foo(){
System.out.println("构造方法");
}
}
在main方法中创建对象:
//创建对象时,首先会在方法区加载Foo类
Foo o = new Foo();//输出:静态块 构造方法
Foo o1 = new Foo();//输出:构造方法
五、final关键字:不可变 ----单独使用的几率不大
1.修饰变量:变量不能被改变
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
a.修饰成员变量:
1).声明的同时初始化
2).构造方法中初始化
b.修饰局部变量:
1).用之前初始化即可
2.修饰方法:方法不能被子类重写
3.修饰类:类不能被继承