面向对象基础(五)

代码块

使用{}花括号定义的一段代码称为代码块,代码块又称为初始化块,属于类的一部分,代码块没有方法名,没有返回值类型,没有参数,代码块将代码写在{}花括号中,在为类开辟内存空间时(加载类的时候)或创建对象时会自动执行代码块

如果多个构造方法中都有重复的语句,可以抽取到代码块中,提高代码的重用性

普通代码块:定义在方法中的代码块

普通代码块写法: 方法{ { 代码..... } }

普通代码块只有在调用其所在的方法时才会执行,每调用一次其所在的方法,就会执行一次普通代码块

如果一个方法中既包含了普通代码块,又包含了局部变量,那么会按照代码书写的先后顺序来进行依次加载或执行


构造代码块:定义在类内方法外的代码块(不加static修饰符),也叫实例代码块

构造代码块写法: { 代码..... }

构造代码块/实例代码块只有在创建对象时才会执行,每创建一个对象,就会执行一次构造代码块

构造代码块/实例代码块的执行顺序优先于构造方法

如果一个类中包含多个构造代码块,在编译代码时,编译器会按照构造代码块定义的先后次序依次进行合并,将它们合并成为一个构造代码块

如果一个类中既包含了构造代码块,又包含了成员变量/成员方法,那么会按照代码书写的先后顺序来进行依次加载或执行


静态代码块:类中或方法中使用static定义的代码块称为静态代码块

静态代码块写法: static{ 代码...... }

静态代码块不管生成多少个对象,只会在类的所有的属性(成员变量)和方法(成员方法)等及其内部的信息在方法区开辟内存空间来进行存储时(也就是类加载时)会执行一次且只会执行这一次,其余情况下都不会执行

静态代码块只能直接使用静态方法和静态属性,而普通代码块可以使用所有方法和所有属性

如果一个类中包含多个静态代码块,在编译代码时,编译器会按照静态代码块定义的先后次序依次进行合并,将它们合并成为一个静态代码块

如果一个类中既包含了静态代码块,又包含了静态变量/静态方法,那么会按照代码书写的先后顺序来进行依次加载或执行

内部类

一个类的内部又完整的嵌套了另一个类结构,嵌套这个的类称为内部类,被嵌套的类称之为外部类,也就是在类的内部定义的类叫做内部类,!!!内部类在编译的时候,会生成单独的字节码文件/.class文件!!!

成员内部类/实例内部类:

定义在类内部,成员方法外部且没有static关键字修饰的类叫做成员内部类

成员内部类/实例内部类写法: 外部类{ 修饰符 返回值类型 内部类名{ 代码..... } }

成员内部类/实例内部类的作用域和生命周期是其所属类的范围(也就是所属的类的{}花括号内),也就是它的作用域是整个类

访问外部类同名成员变量写法:外部类名.this.同名成员变量 ,不使用 new 外部类名().同名成员变量 是因为这种方式多创建了一个对象,浪费空间

成员内部类/实例内部类可以直接使用外部类所有权限的非静态(非static)的属性(成员变量)和方法(成员方法),也可以是静态final(static final)的属性(成员变量)和方法(成员方法)

成员内部类/实例内部类其实就相当于(就是)一个成员变量(本质还是一个类),因此成员内部类可以使用任意的访问修饰符(protected,public,private)

创建成员内部类对象写法:外部类名.内部类名 变量名 = 外部对象名.new 内部类名(); 或 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

成员内部类/实例内部类需要通过外部类对象才能创建内部类对象

成员内部类/实例内部类遵循就近原则,自己有的会优先使用自己的,自己没有才会使用外部类的


静态内部类:

定义在类内部,成员方法外部且使用static关键字修饰的类叫做静态内部类

静态内部类写法: 外部类{ 修饰符+static修饰符 返回值类型 内部类名{ 代码..... } }

静态内部类的作用域和生命周期是其所属类的范围(也就是所属的类的{}花括号内),也就是它的作用域是整个类

静态内部类可以直接使用外部类所有权限的静态成员变量和静态成员方法

静态内部类其实就相当于(就是)一个静态成员变量(本质还是一个类),因此成员内部类可以使用任意的访问修饰符(protected,public,private)

创建静态内部类对象写法:外部类名.内部类名 变量名 = new 外部类名.内部类名();

访问外部类同名成员变量写法:外部类名.同名成员变量,这个就是语法规定,因为不能用this,所以记住就好!

静态内部类的好处是:创建静态内部类对象时,不需要先创建外部类对象

静态内部类遵循就近原则,自己有的会优先使用自己的,自己没有才会使用外部类的


局部内部类:

定义在类的方法(成员方法)内部中或代码块内部或构造器内的类称之为局部内部类

局部内部类写法: 外部类{ 修饰符 返回值类型 方法名{ 内部类{ 代码..... } } }

局部内部类可以直接使用外部类所有权限的属性(成员变量)和方法(成员方法)

局部内部类其实就相当于(就是)一个局部变量(本质还是一个类),因此局部内部类不能使用任何访问修饰符

局部内部类的作用域和生命周期就是在其{}花括号内,也就是所属的代码块内

局部内部类遵循就近原则,自己有的会优先使用自己的,自己没有才会使用外部类的

无法在外部其他类直接创建局部内部类的对象,可以通过提供一个在外部类内部创建局部内部类对象的方法来进行使用

访问外部类同名成员变量写法:外部类名.this.同名成员变量 ,不使用 new 外部类名().同名成员变量 是因为这种方式多创建了一个对象,浪费空间


匿名内部类:

定义在类的方法内部或代码块内部或构造器内的没有类名的类称之为匿名内部类,匿名内部类同时还是一个对象,匿名内部类只能创建这么一个对象(只能创建一次对象),不能再额外的创建对象

匿名内部类写法:

外部类 { 修饰符 返回值类型 方法名{ new 类名或接口名(参数) { 代码..... }(此处可以.匿名内部类中的方法); } }

匿名内部类有两层含义,第一层它是一个没有名字的类,这个类继承自或实现我们所写的new关键字后面的类或接口,匿名内部类最多只可以继承自一个类或实现一个接口,我们可以在后面的{}花括号内书写这个没有名字的类的代码,第二层它是一个对象,也就是这个没有名字的类原地创建出来的对象,我们可以对其进行对象的操作

匿名内部类可以直接使用外部类所有权限的属性(成员变量)和方法(成员方法)

匿名内部类只能使用外部类的常量和没有修改过的外部类属性

匿名内部类在右花括号后面必须写;分号作为结束,因为它本质上其实就是在创建对象,也就是创建类的同时也创建了对象

匿名内部类其实就相当于(就是)一个局部变量(本质还是一个类),因此匿名内部类不能使用任何访问修饰符

匿名内部类的作用域和生命周期就是在其{}花括号内,也就是所属的代码块内

匿名内部类遵循就近原则,自己有的会优先使用自己的,自己没有的使用父类的,父类没有的才会使用外部类的

无法在外部其他类中直接使用匿名内部类的属性(成员变量)和方法(成员方法),因为匿名内部类本身就相当于一个局部变量

访问外部类同名成员变量写法:外部类名.this.同名成员变量 ,不使用 new 外部类名().同名成员变量 是因为这种方式多创建了一个对象,浪费空间

继承的概念

面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用

java中只支持单继承,即只能继承一个类,不支持多继承,不可以同时继承多个类

继承可以解决代码复用,当多个类存在相同的属性(成员变量)和成员方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法, 所有的子类不需要重新定义这些属性和方法


当要创建一个子类对象时,首先会将Object祖先类的所有的属性和方法等及其内部的信息在方法区开辟内存空间来进行存储(加载到方法区中),再其次会将父类的所有的属性和方法等及其内部的信息在方法区开辟内存空间来进行存储(加载到方法区中),再会将子类的所有的属性和方法等及其内部的信息在方法区开辟内存空间来进行存储(加载到方法区中)

再我们将类的所有的属性和方法等及其内部的信息在方法区开辟内存空间来进行存储(加载到方法区中)的时候,这时哪个类加载到方法区中了,哪个类就会在方法区中的静态域存储所有静态的成员变量、静态代码块等

之后会先为子类对象在堆上分配一块内存空间,这时开始创建子类对象,创建对象后,首先会去子类的构造方法中找到并执行隐藏或显示写出的super(有无参数),执行super(有无参数)会进入到父类的构造方法中,进入父类构造方法后找到并执行隐藏或显示写出的super(有无参数),进入到Object类的构造方法中,在执行Object的构造方法前,会先执行Object类的属性和实例代码块,再执行Object类的构造方法,此过程中所有的属性都会被存储到子类对象空间的Object类空间中

等Object类的类型特征(父类的属性,构造器,代码块等)都执行/存储结束后,会返回到父类super(有无参数)的地方,这时在执行剩下的构造方法之前,会先执行父类的属性和实例代码块,再执行父类的构造方法,此过程中所有的属性都会被存储到子类对象空间的父类空间中

等父类的类型特征(父类的属性,构造器,代码块等)都执行/存储结束后,会返回到子类super(有无参数)的地方,这时在执行剩下的构造方法之前,会先执行子类的属性和实例代码块,再执行子类的构造方法,此过程中所有的属性都会被存储到子类对象空间的子类空间中,至此才完成了创建子类对象

综上所属可以看出,所有辈分的类的对象都存储在一块内存空间中


子类会自动继承(自动拥有)父类的属性(成员变量)和方法(成员方法),但是不会继承构造方法,父类又叫做基类,子类又叫做派生类

子类必须调用父类的构造方法(构造器),完成父类的初始化

继承的语法写法: 修饰符 class 子类 extends 父类 { 代码...... }

子类会继承父类的除构造方法(构造器)以外的所有属性和方法(其实不仅是属性和方法,只要是除了构造方法以外的内容都会被继承),如果一个类没有显示继承其他父类,那么这个类默认继承Object类,如果一个类显示继承了其他父类,那么这个类则不会默认直接继承Object类,而是间接的继承Object类,因为如果父类没有显示继承其他爷爷类,那么父类就默认继承了Object类,总之一个类不管怎么样一定会继承Object类

子类继承的父类的属性(成员变量)会在子类创建对象时在堆中与子类的属性(成员变量)分开进行存储,也就是创建对象时,在堆中会为这个对象开辟内存空间,对象的内存空间中一部分内存空间用来存储子类自己的属性(成员变量),一部分内存空间用来存储父类继承下来的类型特征(父类的属性,构造器,代码块等)

子类继承了除父类构造方法外的所有属性(成员变量)和方法(成员方法),但私有属性和方法不能在子类直接使用, 要通过父类提供公共的方法来使用

属性(成员变量)与方法(成员方法)访问遵循就近原则,自己有优先使用自己的,如果没有则向父类中寻找,如果父类也没有,则向爷爷类(父类)再中再寻找,如果都没有则报错

若父类是默认的构造方法或者定义了无参构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用父类构造方法

如果父类定义的构造方法是带有参数的,此时编译器不会再给子类生成默认的构造方法,此时需要用户为子类手动定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败

在子类构造方法中,super(参数)调用父类构造时,必须是子类构造函数中第一条语句!!super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

子类继承父类的话,父类中使用private关键字修饰的属性(成员变量)或方法(成员方法)不可以在子类中使用,但是会被继承

super关键字

super关键字的作用是在子类中使用父类的属性(成员变量)或方法(成员方法)

super关键字其实就是在子类对象空间中存储的父类类型特征(父类的属性,构造器,代码块等)的内存地址(引用地址),也就是父类类型特征(父类的属性,构造器,代码块等)在子类内存空间中的那块内存的地址

使用父类同名属性(成员变量)或方法(成员方法)写法:super.属性名/方法名;

super关键字并不仅限于查找父类,如果父类没有这个super.属性名/方法名,则会向上查找爷爷类的有没有,依此类推,如果没有找到则报错

如果在子类的构造方法中既没有显示定义this()也没有显示定义super()的话,那么在子类构造方法第一行默认有隐含的super()调用,即调用父类构造方法,它会一直追溯到Object类的构造方法为止

super.属性名/方法名不可以使用private关键字修饰的属性(成员变量)或方法(成员方法)

super关键字只能在非静态(非static)的方法(成员方法)中使用,java中允许在子类中出现和父类同名的属性

super关键字是在子类对象对象空间中的父类类型特征(父类的属性,构造器,代码块等)的内存地址(引用地址)

在子类构造方法中,可以使用super(参数)调用父类的构造方法,这种使用方式必须放在构造方法内,必须放在构造方法的第一行(第一句代码)!!!super(参数)不可以和this(参数)同时出现

父子父子是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,然后再调用子类自己的构造方法

如果在子类的构造方法中既没有显示定义this()也没有显示定义super()的话,那么在子类构造方法第一行默认有隐含的super()调用,即调用父类构造方法,它会一直追溯到Object类的构造方法为止

如果父类定义的构造方法是带有参数的,此时编译器不会再给子类生成默认的构造方法,此时需要用户为子类手动定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败

在子类构造方法中,super(参数)调用父类构造时,必须是子类构造函数中第一条语句!!super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

属性(成员变量)与方法(成员方法)访问遵循就近原则,自己有优先使用自己的,如果没有则向父类中寻找,如果父类也没有,则向爷爷类(父类)再中再寻找,如果都没有则报错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值