一、面向对象和面向过程的区别
面向过程的思维方式是简单的线性思维,思考问题首先考虑第一步做什么、第二部做什么的细节,适合计较简单的事情。
面向过程的思维方式首先会解决问题需要那些分类,然后对这些分类进行思考,最后才对某个分类的细节进行面向过程的思索。
对描述复杂的食物,为了从宏观上把握、从整体上合理分析,我们需要面向对象的思路来分析整个系统。但是,具体到围观操作,仍然需要面向过程的思路去解决问题。
二、面向对象编程(Object-Oriented Programming,OOP)
面向对象编程就是采用面向对象的语言如java进行编程,其本质就是:以类的方式组织代码,以对象的方式组织(封装)数据。
A.类和对象的关系
类是一种抽象(abstract)的数据类型,她是对某一类事物整体描述定义,但不能代表某一个具体的事物。对象是抽象概念的具体实例。
如动物类是对所有能自己动的生物的整体抽象定义,而自家养的大橘则是动物类的一个具体的实例。
通常一个类有自己的属性(外貌、性别、年龄等)也叫成员变量,和自己的功能(吃饭、买东西、写字等)也叫成员方法。类中的属性和功能不能直接调用,要通过这个类的对象来调用。
一个java文件中允许定义多个类,但是只能有一个类可以被public修饰 一般是有主方法的那个类
a.创建类
修饰符+class+类名{
属性类型+属性名;
功能
}
举例
public class Student{
String name;//成员变量
public void walk(){//成员方法
System.out.println("我在走路");
}
}
b.创建与初始化对象:使用new关键字创建对象(创建对象得在类中才能创建)
对象和引用的关系:
两者间的关系就是引用指向对象
使用类类型、数组类型、接口类型声明出的变量被称为引用变量,简称引用。
在程序中创建出的对象我们不方便直接使用,需要一个引用类型的变量来接受它,这就是引用指向对象。引用代表着对象。
创建对象格式:对象引用类型+对象名 = new 对象实际类型();
举例:
Student yangbo = new Student();//yangbo是一个引用类型变量,接受对象后,用它来指向(代表)对象。
创建好的对象在调用类的属性和方法时可以直接通过“.”+属性/方法
举例
yangbo.name = "YangBo"
yangbo.waik();
B.方法的回顾与加深
1.方法的定义
修饰符+返回类型+方法名+(参数列表)+异常抛出型{…}
一个方法可以有多个修饰符,这些修饰符是没有先后顺序的。
方法执行完后如果有需要返回的数据,就要声明返回数据的类型;如果没有,返回类型写void;只有构造器(构造方法)不需要返回数据也不用void。
//return和break的区别:
return 语句的作用
(1) return 从当前的方法中退出,返回到//该调用的方法的语句处,继续执行。
(2) return 返回一个值给调用该方法的语句,返回值的数据类型必须与方法的声明中的返回值的类型一致。
(3) return后面也可以不带参数,不带参数就是返回空,其实主要目的就是用于想中断函数执行,返回调用函数处。
break语句的作用
(1)break在循环体内,强行结束循环的执行,也就是结束整个循环过程,不在判断执行循环的条件是否成立,直接//转向循环语句下面的语句。
(2)当break出现在循环体中的switch语句体内时,其作用只是跳出该switch语句体。
2.方法的调用
在类中定义的方法的代码块不会被立马使用,只有在这个方法被调用时代码快才会被一行一行地顺序执行。
a.非静态方法
没有被static修饰的方法就是非静态方法,调用这个方法时“一定”要有对象(非静态属性也是)。
b.静态方法
被static修饰的方法就是静态方法,调用静态方法时“可以”使用对象来调用,也“可以”使用类来调用,但推荐使用类来调用,因为静态方法是属于类的。
c.类中方法之间的调用
类中方法的调用,当两个方法都是静态方法或非静态方法时,两个方法之间可以相互调用,否则只能是非静态方法调用静态方法。//同一个类中,静态方法不能直接访问到类中的非静态属性。
3.调用方法时传参
a.形参和实参
// a = x;
public void test(int a){
//..
}
main:
int x = 1;
t.test(x);
参数列表中a是方法test的形参(形式参数),调用方法时x是方法text的实参(实际参数)。
形参和实参都是一个变量的名字,是可以随便写的,我们不关心变量的名字,而是关心这个变量的类型和接收的值。
b.值传递和引用传递
调用方法传参时分为值传递和引用传递。
当参数类型是基本数据类型时就是值传递,值传递是把自己变量本身存在的简单数值赋值给形参。 当参数类型是基本数据类型时,形式参数的改变不影响实际参数
当参数类型是引用数据类型时那么就是引用传递,引用传递是把自己变量本身存的内存地址值传给形参。 当参数类型是引用数据类型时,形式参数的改变也会改变实际参数
public class Demo{
public static void main(String[] args){
int a = 10;
test(a);//test(a) 值传递 等同于 test(10)
System.out.println(a);// 此处的a实际访问的还是第一行的a 值为10
CC cc = new CC();
cc.num = 50;
test(cc);
System.out.println(cc.num);//1000
}
public static void test(int a){// 此处的a可以换成b.c.d.e等其他名字 test(10)
a = a+10;//b = b+10
}
public static void test(CC cc){
cc.num = 1000;
}
}
class CC{
int num;
public void show(int num){
System.out.println(num);
}
}
两者本质相同,只是传递东西的意义不同
4.this关键字
在类中,用this关键字表特殊作用。
this 代表本类的引用对象,谁调用我这个方法,this就代表谁
a.this关键字在类中的作用
-
区别成员变量和局部变量
public class Student{ private String name; public void setName(String name){ //this.name表示类中的属性name this.name = name; } }
-
调用类中的其他方法
public class Student{ private String name; public void setName(String name){ this.name = name; } public void print(){ //表示调用当前类中的setName方法 this.setName("tom"); } }
-
调用类中的其他构造器
public class Student{ private String name; public Student(){ //调用一个参数的构造器,并且参数的类型是String this("tom"); } public Student(String name){ this.name = name; } }
this的这种用法,只能在构造器中使用.普通的方法是不能用的.并且这局调用的代码只能出现在构造器中的第一句.
b.this关键字在类中的意义
this关键字在类中表示将来创建出的对象。
【例子】
public class Student{
private String name;
public Student(){
System.out.println("this = "+this);
}
public static void main(String[] args){
Student s = new Student();
System.out.println("s = "+s);
}
}
运行后看结果可知,this和s打印的结果是一样的,那么其实也就是变量s是从对象的外部执行对象,而this是在对象的内部执行对象本身.
这样也就能理解为什么this.name代表的是成员变量,this.setName(“tom”)代表的是调用成员方法,因为这俩句代码从本质上讲,和在对象外部使用变量s来调用是一样的,s.name和s.setName(“tom”)。
【this和s打印出来的内存地址是一样的,使用==比较的结果为true。】
public class Student{
public Student getStudent(){
return this;
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = s1.getStudent();
System.out.println(s1 == s2);//true
}
}
【 类中的this是和s1相等还是和s2相等呢?】
public class Student{
private String name;
public void test(){
System.out.println(this);
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.test();
s2.test();
}
}
注:这句话是要这么来描述的,s1对象中的this和s1相等,s2对象中的this和s2相等,因为类是模板,模板中写的this并不是只有一个,**每个对象中都有一个属于自己的this,**就是每个对象中都一个属于自己的name属性一样.
https://www.cnblogs.com/yyy6/p/8976584.html
5.static关键字
static 状态修饰符 静态的 可以修饰成员变量 也可以修饰方法
修饰成员变量就变成了共享变量
public class Student{
String name;
String country;
}
Student s1 = new Student;
Student s2 = new Student;
Student s3 = new Student;
s1.name = "zhangsan";
s1.country = "zhongguo";
s2.name = "lisi";
s2.country = "riben";
s3.name = "wangwu";
s3.country = "meiguo";
System.out.println(s1.name);//zhangsan
System.out.println(s1.country);//zhongguo
System.out.println(s2.name);//lisi
System.out.println(s2.country);//riben
System.out.println(s3.name);//wangwu
System.out.println(s3.country);//meiguo
public class Student{
String name;
static String country;//static 修饰成员变量,使其变为共享变量 存在方法区的静态区 被这个类所有对象共享 该类对象使用同一个country变量,而不是三个
}
Student s1 = new Student;
Student s2 = new Student;
Student s3 = new Student;
s1.name = "zhangsan";
s1.country = "zhongguo";//将country成员变量设为zhongguo
s2.name = "lisi";
s3.name = "wangwu";
System.out.println(s1.country);//zhongguo
System.out.println(s2.country);//zhongguo 与s1是同一个country变量
System.out.println(s3.country);//zhongguo 与s1是同一个country变量
6.super关键字
//super是指向父类的引用,代表父类空间的标示,通过supper可以访问父类的数据
supper.成员变量名
supper.成员方法名
supper().访问父类的空参构造
supper(参数).访问父类的有参构造
//this代表本类的引用
this.成员变量名
this.成员方法名
this().访问父类的空参构造
this(参数).访问父类的有参构造
如果子类方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()父类空参构造方法调用。如果父类由没有默认的无参构造方法,编译器就会报错,super()语句必须是构造方法的第一个子句。
定义子类的一个对象时,会先调用子类的构造函数,然后在调用父类的构造函数,如果父类函数足够多的话,会一直调用到最终的父类构造函数,函数调用时会使用栈空间,所以按照入栈的顺序,最先进入的是子类的构造函数,然后才是邻近的父类构造函数,最后在栈顶的是最终的父类构造函数,构造函数执行是则按照从栈顶到栈底的顺序依次执行.
现在以Bird–> Animal --> Object 为线举例说明
[](javascript:void(0)?
public class Animal {
int eye = 2;
public Animal(){
super();
System.out.println("动物");
}
public void run(){
System.out.println("动物有不同走路方式");
}
public static void main(String[] args) {
Bird b = new Bird();
b.run();
}
}
class Bird extends Animal{
public Bird(){
super();
System.out.println("鸟类");
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run(); // 通过super可以用父类方法和属性
System.out.println("鸟是飞飞飞飞飞飞");
System.out.println("鸟类有"+super.eye+"只眼睛");
}
}
[](javascript:void(0)?
打印结果
动物
鸟类
动物有不同走路方式
鸟是飞飞飞飞飞飞
鸟类有2只眼睛
Bird–> Animal --> Object 图形分析如下
[外链图片转存失败(img-RodcRu3o-1564046177142)(C:\Users\Administrator\Desktop\1026930-20180501170153513-1275315563.png)]
7. this和super异同
1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句)
2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
3)super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
4)this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
5)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
6)super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。
7)super()和this()均需放在构造方法内第一行。
8)尽管可以用this调用一个构造器,但却不能调用两个。
9)this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
10)this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
11)从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
8.方法的重载和重写
重载:允许同一个类型中有多个同名方法,只要他们的参数类型或参数个数不同
重写:
C.面向对象编程的三大特征
1.继承
继承是类和类之间的一种关系,可以提高代码的重复利用性。
继承关系中的两个类,在被继承的是父类(基类),在继承的是子类(派生类)。子类从父类里继承方法和实例变量,子类可以修改或者增加新的方法使其更适合特别的需要。子类继承父类用关键字extends表示。
格式:
public class Person{
String name;
public void walk(){
System.ou.println("我在走路");
}
}
class Student extends Person{
String name;
public void walk(){
System.ou.println("学生在走路");
}
java中类和类之间继承是单继承,一个子类只能直接继承一个父类,就像一个人只能有一个亲生父亲;一个父类可以被多个子类继承,就像一个父亲有多个孩子。
2.封装
我们在定义一个对象的特性时,出于方便和安全的考虑会需要决定这些特性的可见性,哪些对外部可见,哪些用于内部表示,封装就是将那些不用于向外部表示的数据隐藏起来。
通常,应禁止直接访问一个对象中数据的实际表示,而是通过特定方法来进行访问。
a.封装的步骤
-
使用private权限修饰符修饰需要封装的成员变量
-
提供一个公开的方法设置或访问私有属性
在java中可以通过快捷键alt+回车选择get and set来快速创建访问get和设置set的方法
b.封装的作用和意义
- 提高程序安全,保护数据
- 隐藏代码实现细节,更加方便整洁
- 统一用户的调用借口
- 提高系统的可维护性
3.多态
a.多态的前提条件
- 子类继承父类
- 子类重写父类方法(否则多态没有意义)
- 父类引用指向子类对象
b.定义
所谓多态,就是指一个对象在不同引用(声明)类型下可以运行不同方法。也可以理解为,多态是指通过指向父类的指针,来调用在不同子类中实现的方法。
public class Person{};
class Student extends Person{};
class Teacher extends Person{};
Person a = new Student();//a是一个新建的Student类对象,a是Person类(a只能使用Person类的方法)
Student b = new Student();
一个对象的实际类型是确定的(new Student()),但它的引用类型有很多,可以是这个对象实际类型的任意父类型。
父类引用指向子类对象案例:
public class Parents{
int age = 40;
String sex;
public void eat(){
System.out.println("父母爱吃面!");
}
public void walk(){
System.out.println("晚上跑步");
}
}
class Son extends Parents{
int age = 15;
String name = "小明";
public void eat(){
System.out.println("儿子爱吃零食!");
}
public void play(){
System.out.println("儿子爱玩游戏!");
}
}
public class Test{
public static void main(String[] args){
Son a = new Son();
Parents b = new Son();
System.out.println(a.age);//15
System.out.println(a.sex);//null
System.out.println(a.name);//小明
a.eat();//儿子爱吃零食!
a.play();//儿子爱玩游戏!
a.walk();//晚上跑步
System.out.println(((Son) b).name);//b.name错误
System.out.println(((Son) b).age);//b.age错误
System.out.println(b.sex);//null
b.eat();//儿子爱吃零食!
b.walk();//晚上跑步
((Son) b).play();//b.play()错误
}
}
总结:父类引用指向子类对象时,
- 子类独有的方法不能直接被使用
- 父类方法被子类重写的,使用子类的方法
- 父类方法未被重写的,使用父类的方法
必须将父类引用强转为子类引用才能直接访问或使用子类的属性或方法,多态是方法的多态
父类引用指向子类对象,当父类引用访问成员变量时,访问的还是父类的成员变量
多态中成员访问的特点
a.成员变量 编译看左边(只要父类有该成员变量就不会报错),运行看左边(运行时访问的还是左边父类的成员变量)
b.构造方法 创建子类对象的时候,会访问父类的构造方法对父类数据进行初始化
c.多态形式调用方法时,编译看左边(等号左边即父类有该方法就不会报错),运行看右边(右边即子类重写过父类的该方法,运行时就会调用子类的方法) 被static修饰的方法不会被重写 多态形式下 也就不会调用子类中的该同名方法 静态方法调用推荐使用类名调用
D.权限修饰符
权限修饰符 | 同包同类 | 同包 | 不同包子类 | 不同包非子类 |
---|---|---|---|---|
public | Y | Y | Y | Y |
protect | Y | Y | Y | N |
无修饰 | Y | Y | N | N |
private | Y | N | N | N |
三、抽象类
abstract 抽象的 可以修饰方法变为抽象方法(没有具体实现方法体的方法,具体实现交给子类去做) 修饰类 抽象类
抽象类概述
回想前面我们的猫狗案例,提取出了一个动物类。并且我们在前面也创建过了动物对象,其实这是不对的。
为什么呢?因为,我说动物,你知道我说的是什么动物吗?只有看到了具体的动物,你才知道,这是什么动物。
所以说,动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。
同理,我们也可以推想,不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
public abstract class Animal{//类中如果有抽象方法,该类必须定义为抽象类
public abstract void eat();//不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是应该给出一个声明即可。
}
一个类中 可以没有抽象方法 ,但一旦有了抽象方法,这个类必须为抽象类
一个普通类如果继承了一个抽象类,抽象类中的所有抽象方法该类必须全部重写
抽象类中可以定义成员变量,也可以定义常量
抽象类中可以有构造方法,用于子类访问父类数据时的初始化
抽象类中可以有抽象方法(强制子类必须重写),也可以有非抽象方法
抽象类特点:1.抽象类不能直接实例化 不能直接new
2.我们可以采用多态的形式间接实例化
Animal animal = new Cat();
四、接口
现在的驯兽师可以将猫狗之类的动物 训练得可以钻火圈、做算术,这些额外的功能我们不能把它们和猫或狗之类的动物本身就具有的如捉老鼠、睡觉等功能混在一起、归为一类,我们不能在定义猫类狗类时将这些功能也写上去。
因此,在java中为了体现事物功能的扩展性,java提供了接口来接收这些额外功能,并不给出具体实现
将来哪些猫狗需要实现这些额外功能,只需要实现(或安装)上这些接口就行
A、了解接口
与类同级别,
用来定义事物的一些扩展功能,哪些事物想要具备这些功能,只需要实现(安装)上这些接口就行
接口设计理念:1.定义一些规范 2.实现一些额外功能
B、定义接口
使用关键字interface
public interface FireInterface{//定义一个钻火圈的接口
//接口中定义的是抽象方法
public abstract void fire();
}
C、实现接口功能
接口不能直接实例化,不能new接口对象 想要实例化就只能通过多态方式 父接口引用指向子实现类对象
使用关键字 implements(译为实现)
时public interface FireInterface{//定义一个钻火圈的接口
//接口中定义的是抽象方法
public abstract void fire();//接口中的钻火圈方法
}
public class Animal{
public void sleep(){
System.out.println("chi");
}//定义的是该类本身具有的功能
public void eat(){
System.out.println("shui");
}
}
public class Cat extends Animal{
public void sleep(){
System.out.println("mao shui");
}
public void eat(){
System.out.println("mao chi");
}
}
//狗要实现钻火圈功能 就要继承钻火圈接口 成为钻火圈接口的子实现类 并重写接口中的所有抽象方法
public class Dog extends Animal implements FireInterface{
public void sleep(){
System.out.println("gou shui");
}
public void eat(){
System.out.println("gou chi");
}
public void fire(){//重写接口中的钻火圈方法
System.out.println("狗被训练后可以钻火圈");
}
}
public class Text{
public static void main(String[] args){
Dog dog = new Dog();
FireInterface f = dog;//可以将狗和钻火圈接口的关系看成继承关系(实际是实现关系) 钻火圈接口是父类接口 狗是子实现类 此处可以看成父类FireInterface接口的引用指向子实现类对象dog 是多态的表现
f.fire();//调用子类重写过的fire方法 "狗被训练后可以钻火圈"
}
}
接口的子类 可以是抽象类 但意义不大
可以是具体类 需要重写接口中的抽象方法
普通类要实现一个接口,就要重写接口中的所有抽象方法
D.接口的语法特点:
public interface MyInterface{
1.没有成员变量 只有公共静态常量
int num = 100;//这不是一个成员变量 而是一个公共的静态常量 前面有默认的修饰符public static final
public static final int NUM = 100; //因此接口名就可以直接访问
int VALUE = 15;//公共的静态常量
2.接口中全是抽象方法
void bb();//默认有public abstract修饰
public abstract void bb();
public abstract void bb(){}//错误!!只能是抽象方法
3.接口中没有构造方法
}
E.类与类的关系 类与接口的关系 接口和接口的关系
1.类与类的关系
类与类 只有继承关系 只能是单继承
2.类与接口的关系
类与接口是实现关系 implements 一个类可以实现多个接口
interface A{}
interface B{}
interface C{}
class MyClass inplements A,B,C{
//每个接口的方法都必须全部重写实现
}
一个类在继承一个类时也可以实现一个或多个接口 继承关系写在前面
3.接口和接口的关系
接口和接口 是继承关系 可以多继承
interface A{
void a();
}
interface B{
void b();
}
interface C extends A,B{//有自己一个和继承的两个共三个抽象方法
void c();
}
class D implements C{
//必须实现C接口的所有三个抽象方法
}
抽象类和接口的区别
1.成员变量上:抽象类中可以定义成员变量也可以定义常量 接口中只能是公共的静态常量,使用接口名可以直接访问
2.构造方法上:抽象类中有构造方法,接口中没有构造方法
3.成员方法:抽象类中可以有抽象方法,也可以有非抽象方法 接口中只能有抽象方法(JDK 1.7之前,JDK1.8之后可以定义默认方法—前面必须要用default修饰,默认方法可以有方法体)
4.设计理念的区别:抽象类体现一种 is a 的关系,体现的是共享的功能
接口是 like a 的关系,体现的是扩展的功能
5.共同点:抽象类和接口都不能直接实例化 直接new对象
五、内部类
定义在一个类内部的类成为内部类
根据内部类的定义位置不同分为成员内部类和局部内部类
成员内部类是将内部类定义到外部类的成员位置(类中方法外)
将内部类定义到外部类局部位置(成员方法中)
A.成员内部类
public class OutClass{
public int num;
private int a ;
class InnerClass{
int b;
public void innerShow(){
System.out.println("nei show");
}
}
public void show(){
System.out.println("wai show");
}
private void test(){
System.out.println("wai siyou fangfa");
}
}
public class text{
//调用成员内部类方法 需要创建成员内部类对象
OuterClass.InnerClass oi = new OuterClass().new InnerClass();
oi.innerShow();
//内部类的特点:内部类可以直接访问外部类的成员,包括私有的成员
}
内部类可以直接访问外部类的成员,包括私有的成员
外部类想要调用内部类成员,需要创建内部类对象
内部类可以用private修饰 外界无法创建内部类对象、无法访问内部类成员变量 、调用内部类成员方法 ,只能在外部类内创建内部类对象、访问内部类成员方法 、调用内部类成员方法
外界想要访问私有内部类成员变量,可以通过外部类方法
OuterClass.this.num 在内部类中访问外部类的同名成员变量 OuterClass.this代表外部类对象或者直接 new OuterClass()
内部类可以用static修饰 外界创建内部类对象的语法会更简洁
public class text{
//OuterClass.InnerClass oi = new OuterClass().new InnerClass(); 未被修饰前
OuterClass.InnerClass in = new OutCalss.InnerClass(); //static修饰后
}
静态内部类只能访问外部类的静态成员
B、局部内部类
class Outer{
int num ;
private int a;
public void waishow(int num){//局部位置
class Inner{//局部内部类
int aa = 2;
public void neishow(){
}
}
}
}
public class MyTest{//局部内部类在外界没有创建它的语法
public static void main(String[] args){
}
}
在局部内部类里想要访问外部类的局部变量,那这个局部变量要加上final使其成为常量,JDK1.8后会默认加上
C.匿名内部类
是局部内部类的一种简写方式
本质上是一个对象,是实现了该接口或 继承了该抽象类的子类对象
前提条件:要有一个接口或抽象类(普通类也行)
//语法
new 接口或抽象类名(){
重写的方法
};
//势力
abstract class Animal{
public abstract void eat();
}
class Dod exten
Class()
内部类可以用static修饰 外界创建内部类对象的语法会更简洁
public class text{
//OuterClass.InnerClass oi = new OuterClass().new InnerClass(); 未被修饰前
OuterClass.InnerClass in = new OutCalss.InnerClass(); //static修饰后
}
静态内部类只能访问外部类的静态成员
B、局部内部类
class Outer{
int num ;
private int a;
public void waishow(int num){//局部位置
class Inner{//局部内部类
int aa = 2;
public void neishow(){
}
}
}
}
public class MyTest{//局部内部类在外界没有创建它的语法
public static void main(String[] args){
}
}
在局部内部类里想要访问外部类的局部变量,那这个局部变量要加上final使其成为常量,JDK1.8后会默认加上
C.匿名内部类
是局部内部类的一种简写方式
本质上是一个对象,是实现了该接口或 继承了该抽象类的子类对象
前提条件:要有一个接口或抽象类(普通类也行)
//语法
new 接口或抽象类名(){
重写的方法
};
//势力
abstract class Animal{
public abstract void eat();
}
class Dod exten