第一章、思路
-
语言语法基础
命名规则、关键字、数据类型、运算、程序流程控制…
-
方法
调用、方法类别…
-
类
接口、注解、语言编程特性、api…
-
框架
SSM、Spring Boot…
第二章、方法
2.1、定义与调用
(1)标准格式
public static int【返回数据类型】 方法名【小驼峰】(参数列表){
//方法体;
//void无返回值,return省略。
return 返回值;
}
(2)方法的三要素
- 方法名
- 参数列表(参数如果有多个,中间用逗号分隔)
- 返回值
(3)方法调用(类内调用)
调用分为两种,一种是类之间的方法调用,通常会使用该类的对象调用其方法,如果方法是静态的,则使用类名调用该方法;另一种是类内部(或继承、)调用间的调用,调用方式主要如下:
- 单独使用
public static class Method{
public static void main(String[] args){
int a=10;
int b=20;
sum(a,b);
public static int sum(int a,int b){
int result=a+b;
System.out.println(result);
}
}
}
- 打印调用
public static class Method{
public static void main(String[] args){
int a=10;
int b=20;
System.out.println(sum(a,b));
public static int sum(int a,int b){
int result=a+b;
return result;
}
}
}
③赋值调用
public static class Method{
public static void main(String[] args){
int a=10;
int b=20;
int c=sum(a,b);
System.out.println(c);
public static int sum(int a,int b){
int result=a+b;
return result;
}
}
}
④对象调用
Person p1 = new Person();
Person p2 = new Person();
boolean a =p1.equals(p2);
(3)注意事项
①方法应该定义在类中,但不能在方法中再定义方法,不能嵌套。
②方法定义前后顺序无所谓。
③方法定义后,如果不调用就不会执行。
④如果方法有返回值,必须写上return。
⑤return返回值的数据类型必须和方法的返回值类型一致。
⑥对于一个void没有返回值的方法,不能写return后面的返回值,只能够写自己。
⑦一个方法中可以有多个return语句,但是需保证return只执行一个。
2.2、方法重载(@overload)
(1)概念:在一个类中,存在方法名称相同但参数列表不同的方法,这种情况,叫做方法重载。
(2)注意事项
①重载只与参数列表有关,参数列表数量、类型、顺序不同,就可以重载。
public class MethodOverLoad{
public static void main(String[] args){
public static void myPrint(int num,long num1){
sum=num+num1;
System.out.println(sum)
}
public static void myPrint(char num,long num1){
sum=num+num1;
System.out.println(sum)
}
public static void myPrint(long num1,int num){
sum=num+num1;
System.out.println(sum)
}
public static void myPrint(int num){
System.out.println(num)
}
}
}
②重载与方法名称、返回值类型无关。
第三章、类
3.1、面向对象的编程思想
(1)面向对象编程的理解
①人开门
面向过程:人打开门
面向对象:把人和门分成两个对象,也就是两个类。“人”的类中有“打开”的方法,把“门”对象传进去,然后再调 用“门”类的“开”的方法
②人把大象装进冰箱里
面向过程:1)打开冰箱 2)把大象装进去 3)关闭冰箱门
面向对象:把“人”和“大象”,“冰箱”分成三个类,“人”有“打开”和“操作”,“关闭”三个方法,“冰箱”有“开”和“合上”两个方法,“大象”
(2)类(class)
①类是对一个事物的描述,是抽象的。
②类描述事物是由属性和行为构成,属性是成员变量,行为是成员方法。
public class Demo01{
//成员变量(属性)
String name;
String age;
//成员方法(行为)
public void eat(){
System.out.println("吃饭饭");
}
public void sleep(){
System.out.println("睡觉觉");
}
public void study(){
System.out.println("学习习");
}
}
(3)对象(instance)
①对象实际是对一类事物的具现个体,因此也被称为实例。
public static class Demo{
public static void main(String[] args){
//demo01是类名。
Demo01 stu1 = new Demo01();//实例化对象
}
}
(4)类与对象的关系
类是对象的模板,对象是对类的实现。
3.2、类的创建及使用
(1)、类的创建
public class 类名称(大驼峰命名){
//成员变量可赋值也可不赋值,根据实际。
//执行语句只能写在方法体内,否则会报错。
成员变量;
成员方法;
}
(2)类的使用
①导包:创建类时,如果使用到其他类,则需要导包。如果使用到的其他类与当前类在同一个包内,则不需要导包。(idea快捷键Alt+回车)
②使用成员变量(属性)或使用成员方法(方法)。
package ...//当前类所在包位置
//导包语句(lang包不需要,其余都需要)
import ...
//类
public static class Demo{
public static void main(String[] args){
Demo01 stu1 = new Demo01();//实例化对象
//使用成员方法:对象名.成员变量名
//如果成员变量没有赋值,那么将是默认值。
stu1.name;
stu1.age;
//使用成员变量:对象名.成员方法名
stu1.eat();
stu1.sleep;
stu1.study;
}
}
③改变成员变量的值只需要重新赋值。
(3)使用对象类型作为方法参数
①代码示例
public class Demo{
public static void main (String[] args){
Phone apple = new Phone();
method(apple);//调用成员方法,对象类作为参数。
public static void method(Phone param){
System,out,println(param.phoneType+param.sort);
}
}
}
public class Phone{//自定义对象类
int phonteType;
public void sort(){
System.out.println("我会照相");
}
}
②传递参数的对象参数实际是该对象的地址值。
(4)使用对象类型作为方法返回值
(1)代码示例
public class Phone{
String name;
String storage;
String color;
}
public class Demo{
public void main (String[] args){
Phone two = getPhone;//对象two实际得到的是one对象的地址值。
System.out.println(two.name);
System.out.println(two.storage);
System.out.println(two.color);
public static Phone getPhone(){
Phone one = new Phone();
one.name ="apple";
one.storage = "256G";
one.color = "red";
return one;
}
}
}
3.3、成员变量与局部变量
(1)局部变量
①写在类的方法内部。
②只在该方法范围内有效。
③无默认值,如果要使用,必须先赋值。
④位于栈内存。
⑤、 随方法进栈而创建,随方法出栈而销毁。
(2)成员变量
①写在类中的变量。
②在该类里都可以使用。
③有默认值,规则如数组。
④位于堆内存。
⑤岁对象创建出现在堆内存,岁对象被垃圾回收而消失。
3.4、类的封装性
(1)封装性
封装就是对一些细节进行隐藏,对于外界不可见。
(2)封装性在Java中的体现
①方法就是一种封装。
②关键字private也是一种封装。
(3)private关键字的作用与使用
public class Person{
String name;
private int age;//为了使age数值合理,使用private将需要保护的成员变量进行修饰
public void setAge(int a){
name = a;
}
public int getAge(){
return age.;
}
public void show(){
System.out.println("我叫:"+name+",nianling :"+age+"。")。
}
}
public class Demo{
public static void main (String[] args){
Person person = new Person();
person.setAge(10);//该方法用于给被保护的变量赋值。
person.getAge();//该方法用于获取被保护的变量值。
person.show();
}
}
①private关键字,只能在同方法内访问,方法之外无法访问。
②为保证age数值合法,setAge内增加限制age数据的逻辑。
3.5、this关键字
this关键字的两种用法。
①谁调用方法,this代表谁。
②当方法的局部变量和类的成员变量重名的时候,根据就近原则使用局部变量。如果要访问类的同名成员变量,需要使用this关键字。
格式:this.成员变量名
public class Person{
String name;
public void sayHello(String name){
String name;
System.out.println(name + ",你好。我是" + this.name);
//通过谁调用的方法,谁就是this:person调用的sayHello方法,所以this.name等同于person.name。
System.out.println(this);
}
}
public class Demo{
public static void main (String[] args){
Person person = neww Person();
person.name="王健林";
person.sayHello("王思聪");
System.out.println(person);
}
}
3.6、初始化创建对象方式
(1)构造方法
概念:构造方法就是专门用来创建对象的,当时用new创建对象时,其实就是在调用方法。
(2)构造方法格式
①
public 类名称(参数列表){
方法体;
}
②
public class Student{
private String name;
private int age;
//构造方法
public Student(Sting name,int age){
this.name = name;
this.age = age;
}
}
①构建方法的名称必须和所在类名相同。
②构造方法不要写返回自类型,连void都不用写。
③构造方法不能return一个具体的返回值。
④如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,无参,无方法。
⑤构造方法可以重载。
3.7 、Bean
(1)概念
一个标准的类,应具有以下所有部分。这样一个标准的类,也叫做Bean。
①所有的成员变量都要使用private
②为每个成员变量编写一对get、set方法。
③编写一个无参数构造方法。
④编写一个全参数的构造方法。
3.8、匿名对象
(1)省略掉对象名字的对象叫做匿名对象。
(2)匿名对象的创建格式
new 类名称();
(3)使用匿名对象
①匿名对象只能使用一次。
②使用建议:如果确定一个对象只需要使用唯一的一次,就可以用匿名对象。
public class Demo{
public static void main(String[] args){
new person().name = "赵又廷";
new person().showName();//调用发发会报错,因为方法参数name与上一句的name不是用一对象。
}
}
public class Person{
String name;
public static showName(Sting name){
System.out.prinln("我是:"+name);
}
}
(4)匿名对象作为方法的参数和返回值
Public class Demo{
public static void main(String[] args){
showInPut(new InPut("杨又廷"));//匿名方法作为参数。
}
}
public class InPut{
String name;
public InPut(String name){
this.name;
}
public static showInPut(Sting name){
System.out.prinln("输入的是:"+name);
return new Scanner(system.in);//匿名方法作为返回值。
}
}
3.9、数组对象
(1)对象是类的实例化,类是引用数据类型。
(2)创建格式。
Person[] person = new Person[3];//长度为三的Person对象数组。
第四章、继承
4.1、概述
(1)继承的特点
继承是面向对象的三大特征之一。
继承是多态的前提。
继承主要解决的问题是:共性抽取(对象之间共性的属性或者方法)!!!!!!
父类(基类、超类)<-------子类(派生类)
(2)类与类的关系
①关联关系:比如学院和研究生和教授三个之间是关联的关系,就是一个类里可以创建另一个类的属性,比如学院里面肯定有研究生属性,也有教授属性,教授里面也有研究生属性,就是这样一个关系。
②继承关系:运动员下有篮球运动i员,排球运动员,游泳运动员,他们之间的关系是继承关系,两个类之间有共同的特性就可以继承。
③聚集:球队里有队长和队员,他们的关系就是聚集关系,
④组合:人的胳膊,腿,手之间的关系就是组合关系,组合和聚集很像但又不是,聚集中队长可以是另外一支球队的队长,但手和腿只能是一个人的手腿,不能是其他人的,这就是聚集和组合的区别。
4.2、继承的格式
①继承关系中,“子类就是一个父类”,也就是说,子类可以被当做父类看待。
②子类可以使用父类的东西,也可以使用自己定义的东西。
③声明子类对象,会先实例化父类对象,再实例化子类对相关。
public class Fu{
....
}
public class Zi extends Fu{
....
}
4.3、子类对父类的访问
4.3.1、成员访问特点
public class Fu{
int a = 10;
int b = 11;
public void one(){
System.out.println("父类方法一!");
}
public void two(){
Ststem.out.prinln("父类方法二!");
}
}
public class Zi extends Fu{
int a = 12;
int c = 14;
public vid one(){
System.out.println("这是子类方法一!");
}
public void three(){
System.out.println("这是子类方法三!");
}
}
public class Demo{
public static void main(String[] args){
Zi zi = new Zi();
//打印:12
System.out.println(zi.a);
//打印:14
System.out.println(zi.c);
//打印:这是父类方法一!
System.out.println(zi.one);
//打印:这是子类方法三!
System.out.println(zi.three);
//编译报错,父类子类都没有方法four
System.out.println(zi.four);
}
}
①子类对象调用成员,优先使用子类,没有则在父类寻找。
4.3.2、方法重写(覆盖)
(1)概念
在继承关系中,方法名称一样,参数列表也一样。
重写(Override):方法名称一样,参数列表也一样。
重载(Overload):方法名称一样,参数列表不一样。
(2)特点
创建的是子类方法,则优先使用子类方法。
(3)注意事项
①anotation(注解)用来检测操作是否正常
@Override(重载注解)
注解如果不写,只要满足要求,也是正确的方法覆盖重写。
②子类方法返回值必须【小于等于】父类方法的返回值范围。 java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。
③修饰符大小权限
子类方法的权限必须【大于等于】父类方法的修饰符。
public > protected > (default) > private
default并不是关键字,而是什么都不写。
(4)覆盖重写的应用场景
①避免代码重复:对于投入使用的系统尽量不要改动,推荐定义一个新的类,来重复利用其中共性内容,并且添加改动的部分。
②避免系统发生错误:升级或修改系统时,原本类的修改可能牵一发而动全身,所以重写是避免这个问题的方法之一。
4.3.3、构造方法的访问特点
(1)内存层面理解
在创建子类对象时,会把父类里的成员变量和方法也加载进内存(因为要加载进内存,所以要看下这些数据是怎么初始化的,所以调用了父类的构造,仅此而已,并不是去创建了父类对象)
(2)注意事项
①子类构造方法当中,有一个默认隐含的” super(); “调用,所以一定是先执行父类构造,后执行子类构造方法。
②子类构造可以通过super关键字来调用父类重载构造。
③super的父类构造调用,必须是子类构造方法的第一个语句,不能一个子类构造语句调用多次super构造。
public class Fu{
public zi(){
//子类构造,调用父类无参构造。
super();
//本句编译会报错,如果没有super()则不会报错。super(20),20是给父类有参构造传递的参数。
super(20);
System.out.println("子类构造方法!");
}
}
public class Zi extends Fu{
//重载父类无参构造方法
public fu(){
System.out.println("父类无参构造方法!");
}
public fu(int num){
System.out.println("父类有参构造方法!");
}
}
public class Demo{
public static void main (String[] args){
Zi zi = new Zi();
}
}
总结:子类必须调用父类构造方法,不写则赠送super()关键字,写了 则用写的指定的super调用,super只能有一个,还必须是第一个。
第五章、抽象关系
5.1、概念
(1)举例
①【父类】图形(计算面积方法)————【子类】三角形、圆形、正方形(计算面积方法)
②【父类】动物(吃东西方法)————【子类】猫(吃东西方法)
图形、动物父类有计算面积、吃东西方法,但由于类太抽象,方法体无法定义。如果想要使用这两种方法,就需要子类去覆盖重写方法。
这种情况的父类存在是为了组织项目的类关系,使项目内使用的类得到较好管理。
5.2、抽象的类与方法
(1)声明格式
public abstract class Animal{
public abstract void eat();
}
(2)详解
①抽象方法没有方法体
②抽象方法必须在抽象类内
③不能直接创建抽象类对象,只能通过继承类对象重写使用
④抽象类有构造方法,是供子类创建对象 时初始化父类成员使用的
⑤抽象类中不一定有抽象方法,抽象类也不能直接创建对象,这种抽象类实在特殊场景使用的。
⑥抽象类子类必须重写所有父类抽象方法,除非该子类也是抽象类
5.3、接口与抽象类理解
第六章、接口
6.1、概念
(1)接口在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
(2)声明
public interface 接口名称{
接口内容;
}
①接口是多个类的公共规范。
②接口是一种引用数据类型。
6.2、Java各版本接口内容
6.2.1、Java7
常量
抽象方法
6.2.2、Java8
常量
抽象方法
默认方法
静态方法
6.2.3、Java9
常量
抽象方法
默认方法
静态方法
私有方法
6.3、接口声明与使用
6.3.1、接口声明
public interface MyIterfaceAbstract{
//成员变量(接口常量 interface const)
public static final int num = 10;
//默认方法,解决接口升级问题
public default void defaultMethod(){
方法体;
}
//四种都是抽象方法,关键字可以省略
public abstract void method1();
abstract void method2();
public void method3();
void method4();
//静态方法
public static void methodStatic(){
方法体;
}
//普通私有方法
private void methodPrivate(){
方法体;
}
//静态私有方法
private static void methodPrivate1(){
方法体;
}
}
6.3.2、理解与方法使用
(1)抽象方法
①接口不能直接使用,必须有实现类实现接口
②接口的实现类必须覆盖重写接口中所有抽象方法
③创建实现类对象使用接口
(2)默认方法
①通过接口实现类对象直接调用默认方法
②接口的实现类覆盖重写后调用
(3)静态方法
①不能通过接口实现类对象调用接口静态方法
②通过接口名称,直接调用接口静态方法
(4)私有方法
①普通私有方法解决多个默认方法之间重复代码问题。
②静态私有方法解决多个静态方法之间重复代码的问题。
(5)成员变量
①public static final 三个关键字固定。三个关键字可以省略,但是默认存在。
②因为final关键字,成员变量必须进行赋值
③接口常量名称推荐使用大写字母,用下划线分隔方法
public class Demo1 implements MyIterfaceAbstract{
//默认方法使用
public default void defaultMethod(){
方法体;
}
//抽象方法使用
public abstract method1(){
方法体;
}
}
6.4、继承父类并实现多接口
(1)详解
①接口没有静态代码块或者构造方法
②一个类的直接父类是唯一的,但是一个类可以实现多个接口
public class MyInterfaceImpl implements MyInterface1,MyInterface2{
}
③如果实现类所实现的多个接口当中,存在重复的抽象方法,只需重写一次
④如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类必须是一个抽象类
⑤如果实现类所实现的多个接口当中,存在重读的默认方法,那么实现类一定要对冲突的默认方法重写
⑥一个类如果直接父类当中的方法和接口当中的默认方法产生冲突,优先使用父类当中方法
6.5、接口之间的多继承
(1)类与接口的继承关系
①类与类之间是单继承的,直接父类只有一个
②类与接口是多继承的,一个类可以继承多个接口
③接口与接口之间是多继承的
public interface MyInterface1{
public abstract void method1();
}
public interface MyInterface2{
public abstract void method2();
}
public interface MyIntereface extends MyInterface1,MyInterface2{
}
(2)详解
①多个父类当中抽象方法重复无所谓
②多个父接口默认方法重复,子接口需要对其重写
第七章、多态(Polymorphism)
7.1、概念
一个对象拥有多种形态就叫做对象的多态性。
面向对象的三大特征:封装性、继承性、多态性
extends继承或者implements实现,是多态的前提。
7.2、多态声明
(1)声明
父类引用指向子类对象
public class Fu{
}
public class zi extends Fu{
}
public class Demo{
public static void main(String[] args){
//多态
Fu obj = new Zi();
}
}
7.3、多态使用
7.3.1、成员常量访问特点
①对象引用成员变量优先使用子类,没有则在父类寻找。
②成员变量重名,优先使用子类成员变量
7.3.2、成员方法访问特点
编译看左边(父类),运行看右边(子类)
对于成员方法,编译的时候首先看父类有没有此成员方法,有则编译通过,无则编译不通过,然后执行的时候看子类重写的方法,如果子类没有重写此方法,则执行父类的方法体,实际上也是执行自己的方法,因为子类从父类继承了此方法,所以说也不算是执行了父类的方法
7.4、多态优点
①无论右边new的时候换成哪个子类对象,等号左边调用方法都不会变化
7.5、多态对象转型
对象 instanceof 类型
//得到boolean,判断前面的声明(声明对象、引用对象)能不能作为后面实例(实例对象)的引用
if(animals instanceof dog){
}
if(animals instanceof cat){
}
7.5.1、对象的向上转型
对象向上转型,就是多态声明方法
父类对象 对象名 = new 子类对象();
①向上转型一定是安全的
7.5.2、对象的向下转型
对象的向下转型实际是一个还原动作
子类名称 对象名 = (子类名称)父类对象
//将父类对象,还原成【本来】的子类对象
第八章、关键字
8.1、static
(1)作用
①共享数据:用关键字static修饰的成员或属性,是类的固化属性。一旦使用static修饰成员或方法,那么该成员或方法就不属于对象,而是属于类,数据归多个对象共享。
②声明的对象在堆内存中,并不会有static修饰的属性或方法实例。
(2)关键字修饰成员或方法的使用
①、
对象名.静态成员
//使用这个语句赋值,则所有该对象共享该成员数据。
//静态成员能用作计数器,每次实例化对象,计数器加一
②、
对象名.静态方法 //正确,不推荐
类名称.静态方法 //正确,推荐
(3)注意事项
①静态不能直接访问非静态,因为内存中是先有静态,后有的非静态内容。
当实例化对象时,静态成员会直接被创建,但是非静态并不会有数据(常规情况非静态成员不会给赋值),所以静态不能访问非静态。
②静态方法当中,不能使用this关键字。因为this代表当前对象,对象是类的实例化,类内可能会存在非静态成员。
(4)静态的内存图
(5)静态代码块
public class Person{
static{
System.out.println("静态代码块!");
//第一次用到本类时,静态代码块执行唯一的一次。
//不使用默认构造方法,使用该构造方法。
public Person (){
System.out.println("构造方法!");
}
}
}
public class Demo{
public static void main(String[] args){
//会打印:静态代码块!
Person one = new Person();
//会打印:构造方法!
Person one = new Person();
}
}
①、静态内容要优于非静态,所以静态代码块比构造方法先执行。
②、静态代码块的典型用途:用于一次性地对静态成员变量进行赋值。
8.2、super 与 this
8.2.1、super
①在子类成员方法中,访问父类成员变量。
public class Fu{
int num = 10;
}
public class Zi extends Fu{
super.num;
}
②在子类成员方法中,访问父类成员方法。
public class Fu{
public void method(){
System.out.println("子类方法!");
}
}
public class Zi extends Fu{
super.method;
}
③在子类构造方法中,访问父类构造方法。
8.2.2、this
①本类成员变量中,访问本类的成员变量
②本类的成员方法中,访问本类的另一个成员方法。
③在本类的构造方法中,访问本类的另一个构造方法。该用法,this必须是构造方法的第一句,也是唯一 一个。
④super与this的构造实用,不能同时使用。
8.2.3、super与this的理解
8.3、final
8.3.1、修饰类
(1)声明格式
public final class Demo{
public static void main(String[] args){
...
}
}
(2)详解
①final修饰的类不能有子类(太监类),但是可以有父类
②final类的所有成员方法不能覆盖重写,但是可以重写父类成员方法
8.3.2、修饰方法
(1)声明格式
public class Demo{
public final void method(){
...
}
}
(2)详解
①final修饰的方法不能被覆盖重写
②abstract与final不能同时使用,abstract方法无方法体,必须覆盖重写,final修饰方法不能重写
8.3.3、修饰局部变量
(1)声明格式
public class Student{
private String name;
public Student(){
}
public String Student(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
public class Demo{
public void method(){
int num = 1;
final int num = 2;
final Student stu = new Student("赵丽颖");
//编译报错
stu = new Student("赵又廷");
//编译正常,name值变成高圆圆圆圆
stu.setName("高圆圆圆圆");
}
}
(2)详解
①final修饰局部变量,局部变量值不能改变,相当于常量
②final修饰引用数据类型局部变量,引用数据类型地址值不变,内容可变
8.3.4、修饰成员变量
(1)声明格式
public class Person(){
private String name;
public Person(){
name = “关晓彤”;
}
public String Persion(String name){
this.name = name;
}
public String getName(){
return name;
}
}
(2)详解
①由于成员变量具有默认值,如果用了final修饰,成员变量必须手动赋值,不会有默认值
②必须保证所有重载构造方法对final成员变量进行赋值
8.4、四种权限修饰符
①default并不是关键字而是不写
public> | protected> | (default)> | privtongyile | |
---|---|---|---|---|
同一类 | yes | yes | yes | yes |
同一包 | yes | yes | yes | no |
不同包子类 | yes | yes | no | no |
不同包非子类 | yes | no | no | no |
8.5、native
注册本地方法(本地方法是由JVM实现,底层是C/C++实现的),向JVM进行注册。
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
}
第九章、类的高级嵌套
9.1、内部类的概念与分类
(1)概念
如果一个事物的内部包含另一个事物,那么久是一个类内包含另一个类。
(2)分类
①成员内部类
②局部内部类(包含匿名内部类)
9.2、成员内部类
9.2.1、定义
(1)声明格式
//外部类
public class Body{
//成员内部类
public class Heart{
//内部类方法
public void beat(){
System.out.println("成员内部类");
System.out.println("name");
}
}
public void method(){
//外部类方法
System.out.println("成员方法");
}
private String name = "xxx";
}
(2)详解
①项目文件中,成员内部类单独成文件,文件命名格式:外部类名$内部类名
②成员变量可以被成员内部类直接访问(private关键字限定范围为同一类)
9.2.2、使用
(1)使用方法
①间接使用:在外部类的方法中,使用内部类,然后main只是调用外部类的方法
②直接调用:外部类名称。内部类名称。对象名 = new 内部类名称().外部类名称()
//外部类
public class Body{
//成员内部类
public class Heart{
//内部类方法
public void beat(){
System.out.println("成员内部类");
System.out.println("name");
}
}
public void method(){
//外部类方法
System.out.println("成员方法");
//匿名对象
new Heart().beat();
}
private String name = "xxx";
}
public class Demo{
public static void main(String args[]){
Body body = new Body();
//通过外部类对象调用内部类方法
BOdy..Heart heart = new Body().Heart();
}
}
9.2.3、内部类的同名变量访问
(1)详解
①如果出现中明现象,调用格式:外部类名称.this.外部类成员变量名
9.3、局部内部类
9.3.1、概念
如果一个类是定义在一个方法内部的,那么 这个方法就是一个局部内部类。由于是局部内部类,只有方法内能访问该类。
9.3.2、类权限修饰符使用规则
①外部类:public 、(default)
②成员内部类:所有关键词都可以用
③局部内部类::什么都不写
9.3.3、final问题
局部内部类,如果希望访问所在的方法的局部变量,那么这个局部变亮必须是【有效final】。
从Java 8+开始,只要局部变量事实不变,那么final关键字可以省略。
原因:new出来的对象在堆内存当中,但是局部变量是跟着方法走的没在栈内存当中。当方法运行结束时,方法会立即出栈,局部变量就会消失。new出来的对象会在堆当中持续存在,直到垃圾回收消失。
9.4、匿名内部类
(1)声明格式
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,二改为使用匿名内部类。
接口名称 对象名 = new 接口名称(){
@Override
接口内方法
}
- new代表创建对象的动作
- 接口名称需要实现接口内所有属性