面向对象内存
1.面向对象编程
java是一种面向对象的语言,面向对象编程,英文Object-Oruented Programming,简称OOP
面向对象必须要有对象 new Student也就是new新建一个对象,面向对象编程,是一种通过对象的方式,把现实世界映射到计算机模型的一种方法
2.类
面向对象基本概念:类,实例方法
面向对象实现方式:继承,多态
Java语言本身提供的机制:package,classpath,jar
Java标准库提供的核心类:字符串,包装类型,JavaBean,枚举,常用工具类
3.面向对象实例
public class Student {
//类属性
private int id;
private String name;
private int age;
Book book;
//类方法
void student() {
System.out.println("我正在敲代码" + "和看"+book.brand);
}
void play() {
System.out.println("敲完来把王者农药压压惊!!!");
}
public static void main(String[] args) {
//创建Student类的对象,调用Student类的无参构造方法,系统自动创建
Student stu = new Student();
stu.id = 1;
stu.name = "fff";
stu.age = 18;
Book books = new Book();
books.brand = "Java核心技术";
stu.book = books;
stu.play();
stu.student();
}
public Student() {
//如果有有参构造方法,调用无参需要创建
}
}
class Book{
String brand;
}
4.内存
Java虚拟机的内存可以分为3个区域:栈(stack),堆(heap),方法区(method area)
4.1 栈(stack)
栈的特点:
1.栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量,操作数,方法出口等)
2.JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数,局部变量等)
3.栈属于线程私有,不能实现线程共享
4.栈的存储性是先进后出,后出先进
5.栈是由系统自动分配,速度快,栈是一个连续的内存空间
4.2 堆(heap)
堆的特点:
1.堆用于存储创建好的对象和数组(数组也是对象)
2.JVM只是一个堆,被所有线程所贡献
3.堆是一个不连续的内存空间,分配灵活,速度慢
4.3 方法区(静态区)
方法区的特点:
1.JVM只是一个方法区,被所有的线程所共享
2.方法区实际也是堆,只是用于存储类,常量相关的信息
3.用来存放程序中永远是不变或唯一的内容(类信息 class对象,静态变量,字符串等)
5. 内存执行
javac Student.java -->java Student–>加载Student.class相关信息
方法区加载完,执行main方法,加载main方法的变量stu,一开始为null,stu = null
然后new Student()调用Student()的无参构造方法,在栈里面开辟空间,然后把属性加载的方法区开辟空间(0x11),然后就把方法区的地址赋给stu
stu.id = 1
stu.name = “fff”
stu.age = 18
Book books加载变量c1到main方法中,然后调用new Book()构造方法,加载到栈中,在堆区开辟新空间
books.brand = “java核心技术”
stu.book == books的地址
注意:方法区里面的内容不能找堆里面的内容,只能堆找方法区
6.构造方法
定义:
1. 通过new关键字调用!!
2. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
3. 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加!
4. 构造器的方法名必须和类名一致!
格式:
/*
[修饰符] 类名(形参列表){
//n条语句
}
*/
public class Demo01 {
Student stu = new Student();//调用无参构造方法
Student stu01 = new Student("小二",18);//调用有参构造方法
}
class Student{
private String name;
private int age;
private int id;
public Student() {
//无参构造方法
}
public Student(String name,int age) {
//有参构造方法
super();//调用构造方法不许再第一位
this.age = age;
this.name = name;
this.id = id;
}
public Student(String name,int age.int id){
//三个Student构造方式形成构造方法的重载
this.age = age;
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getId(){
return id;
}
6. this关键字
this的本质就是“创建好的对象的地址”! 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。
this最常的用法:
1. 在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。
2. 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
3. this不能用于static方法中。
7. static关键字
在类中,用static声明的成员变量为静态成员变量,也称为类变量。 类变量的生命周期和类相同,在整个应用程序执行期间都有效。它有如下特点:
1. 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
2. 对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!
3. 一般用“类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)
4. 在static方法中不可直接访问非static的成员。
核心要点:
static修饰的成员变量和方法,从属于类。
普通变量和方法从属于对象的。
public class Demo02 {
private int id;
private String name;
private int age;
static String city = "江西";
public Demo02(int id,String name) {
super();
this.id = id;
this.name = name;
}
public void login() {
printInfo();
System.out.println("登录学生系统:" + name);
}
public static void printInfo() {
//login();//调用非静态的成员方法编译就会报错
//静态方法只能调用静态方法,不能调用非静态方法,非静态方法可以调用静态方法
System.out.println(city);
}
public static void main(String[] args) {
Demo02 de = new Demo02(01,"fw");
de.printInfo(); //江西
de.login(); //江西 fw
de.city = "九江";
de.printInfo();//九江
}
8. 传值机制
基本数据类型传递
Java中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,我们得到的是“原参数的复印件,而不是原件”。因此,复印件改变不会影响原件。
引用数据传递
传递的是值的副本。但是引用类型指的是“对象的地址”。因此,副本和原参数都指向了同一个“地址”,改变“副本指向地址对象的值,也意味着原参数指向对象的值也发生了改变”
9. package
包的命名是域名倒写+实现模块名:com.baidu.index,包的机制是Java管理类的重要手段,我们会遇到大量同名的类,通过包我们很容易解决类重名的问题,也可以时间对类的有效管理,包对于类,相当于文件夹对文件的作用,每个.的前面都是一个文件夹名称
Java常用的包 | 说明 |
---|---|
java.lang | 包含一些Java语言核心类,如String,Math,Integer,System,Thread,提供常用的功能 |
java.awt | 包含了构成抽象窗口工具集(abstract windows toolkits)的多个类,这些类长用于构建和管理应用程序的图形用户界面(GUI) |
java.net | 包含执行与网络相关的操作类 |
java.io | 包含能提供多种输入/输出功能的类 |
java.util | 包含一些实用工具类,如定义系统特性,实用与日期日历相关的函数 |
10. import
我们需要使用系统的API方法或者包的类等方法就需要导入包
import java.util.Date;//导入该包下的Date类
import java.util.*;//导入该包下所有的类,会降低编译速度,但是不会降低运行速度
//上面两种导入,写其中一种就行
Date date = new Date();
//java包下非同名的类不需要完整路径
java.util.Date date = new java.util.Date();//如果上面没有导入包,则需要使用这种
import static java.lang.Math.*;//导入Math类的所有静态属性
import static java.lang.Math.PI;//导入Math类的PI属性
11. 继承extends
面向对象三大特征:继承,多态,封装
1.Java的接口可以多继承,类只能单继承,如果一个类没有继承,那么他的父类就是java.lang.Object
2.父类也叫作超类,基类,派生类等
3.子类继承父类,可以得到父类的全部方法和属性,除了父类的构造方法,如雷的私有化变量不能直接访问
eclipse继承树:右击Open call Hierarchy或选中类ctrl+T
public class Demo01 {
public static void main(String[] args) {
Student stu = new Student();
stu.name = "111";
stu.age = 12;
stu.setPlay("足球");
stu.play();
stu.rest();
stu.study();
Person per = new Person();
per.name = "222";
per.age = 25;
//per.setPlay();//编译不通过,父类不能访问子类,只能之类访问父类
}
}
class Person{
String name;
int age;
public void rest() {
System.out.println("我要休息会");
}
public void play() {
System.out.println("等下去玩球");
}
}
class Student extends Person{
private String play;
public String getPlay() {
return play;
}
public void setPlay(String play) {
this.play = play;
}
public void study() {
System.out.println("学习了两个小时");
}
}
11.2 instanceof运算符
instanceof是二元运算符,左边是对象,右边是类;当对象是运算符的右边类或者子类所创建或时,返回true,否则返回false
stu instanceof Person/Student
注意:是不对象点
11.3 方法重写override
方法重写override;方法重载overload
子类通过重写父类的方法,可以用自身的行为替换父类的行为。方法的重写是实现多态的必要条件
子类需要独特的实现
方法的重写需要符合下面的三个要点:
1.“==”: 方法名、形参列表相同。
2.“≤”:返回值类型和声明异常类型,子类小于等于父类。
3.“≥”: 访问权限,子类大于等于父类。
public class Demo01 {
public static void main(String[] args) {
Father v1 = new Father();
Son v2 = new Son();
Mother v3 = new Mother();
v1.run();
v2.run();
v3.run();
}
}
class Father{//class Father extends Object{} 相当于这个
public void run() {
System.out.println("乘坐公交车上班");
}
public void play() {
System.out.println("玩魔兽世界");
}
public Person who() {//返回乘客
return new Person;
}
}
class Son extends Father{
public void run() {
System.out.println("乘坐地铁上班");
}
public void play() {
System.out.println("玩英雄联盟");
}
public Person who() {//子类重写可以返回Student和Person
return new Person;
}
}
class Mother extends Father{
public void run() {
System.out.println("骑自行车上班");
}
public void play() {
System.out.println("玩王者荣耀");
}
}
12. toString方法
public class Demo01 {
public static void main(String[] args) {
Student stu = new Student();
stu.setAge(15);
stu.setName("dw");
System.out.println(stu);//Student [name=dw, age=15]
//打印stu内部会调用stu.toString,因为集成了Object
}
}
class Student{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
/*
* public String toString() {//源码
return getClass().getName() + "@" + Integer.toHexString(hashCode());
//getClass().getName() 包名+类名 @ 十六进制哈希值
}
*/
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
13. ==,equals与super
“==”代表比较双方是否相同。如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。
Object类中定义有:public boolean equals(Object obj)方法,提供定义“对象内容相等”的逻辑
Object 的 equals 方法默认就是比较两个对象的hashcode,是同一个对象的引用时返回 true 否则返回 false。但是,我们可以根据我们自己的要求重写equals方法。
public class Demo01 {
public static void main(String[] args) {
Student stu = new Student("ww",18);
Student stu01 = new Student("ww",18);
System.out.println(stu.equals(stu01));//false,重写equals后返回true
Student stu02 = stu;//指向同一内存空间,不重写equals也为真
}
}
class Student{
String name;
int age;
public Student(String name,int age) {
super();
this.name = name;
this.age = age;
}
/*
//equals源码
public boolean equals(Object obj) {
return (this == obj);
}
*/
/* 手写
* public boolean equals(Object obj) { Student stu = (Student)obj; return
* this.name.equals(stu.name) && this.age == stu.age; }
*/
//自动生成右击source-->Generate hashCode()and equals()
@Override
public int hashCode() {//加与不加无所谓,集合里面会用到
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {//stu01对象传进来
if (this == obj)//对象地址是否相等
return true;
if (obj == null)//stu01是否为空
return false;
if (getClass() != obj.getClass())//类型不一样就不用了比
return false;
Student other = (Student) obj;//强制把Object类型转换成Student类型
if (age != other.age)//基本数据类型数字==比较值是否相等
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))//判断name里面的内容,是否想等,如果相等,! (非)就不执行下面语句,直接执行return true
return false;
return true;
}
}
13.2 super
1.super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性
2.若是构造方法的第一行代码没有显式的调用super(…)或者this(…);那么Java默认都会调用super(),含义是调用父类的无参数构造方法。这里的super()可以省略
3.使用super调用普通方法,语句没有位置限制,可以在子类中随便调用
public static void main(String[] args) {
System.out.println("我是main方法里面的输出语句");
Student stu = new Student();
System.out.println();
Student stu01 = new Student();
/*输出
我是main方法里面的输出语句
我是静态代码块...上
我是静态代码块...下
我是代码块 ....上
我是代码块 ....下
我是Father的构造方法
我是Son的构造方法
我是代码块 ....上
我是代码块 ....下
我是Father的构造方法
我是Son的构造方法
*/
}
}
class Father{
public void play(){
System.out.println("我是Father类中的玩方法");
}
{
System.out.println("我是代码块 ....上");
}
static {
System.out.println("我是静态代码块...上");
}
public Father(){
//super();这里调用Object
System.out.println("我是Father的构造方法");
}
{
System.out.println("我是代码块 ....下");
}
static {
System.out.println("我是静态代码块...下");
}
public void student() {
System.out.println("我是Father类中的学习方法");
}
}
class Student extends Father{
public Student() {
//super();写与不写都有,调用父类的构造方法
System.out.println("我是Son的构造方法");
}
}
注意:静态代码块只能执行一次,代码块每次调用都会执行
14. 封装
程序设计要追求,高内聚,低耦合;高内聚就是类的内部数据操作细节自己完成,不允许外部干预,低耦合,就是尽量少暴露方法给外部使用,并尽可能的方便外部调用就是不想让用户看见的就全部隐藏起来,这就是封装
封装就是把对象的属性和操作结合为一个独立的整体,并尽可能的隐藏对象的内部实现细节
封装优点:1. 提高代码的安全性。
2. 提高代码的复用性。
3. “高内聚”:封装细节,便于修改内部代码,提高可维护性。
4. “低耦合”:简化外部调用,便于调用者使用,便于扩展和协作
访问权限修饰符
修饰符 | 同一类 | 同一个包 | 子类 | 所有类 | |
---|---|---|---|---|---|
private | √ | 私有自己可以访问 | |||
default | √ | √ | 同一个包的类能访问 | ||
protected | √ | √ | √ | 同一包的类以及其他包中的子类访问 | |
public | √ | √ | √ | √ | 可以被该项目的所有包中的所有类访问 |
类的属性处理: 1. 一般使用private访问权限。
2. 提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是is开头!)。
3. 一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法用public修饰
public class Demo01 {//这种简单的封装也叫JavaBean的封装
public static void main(String[] args) {
Person per = new Person();
//给方法属性赋值
per.setId(01);
per.setName("lly");
per.setAge(12);
per.setMan(false);
System.out.println(per);//Person [id=1, name=lly, age=12, man=false]
}
}
class Person{
//类的属性私有,封装
private int id;
private String name;
private int age;
private boolean man;
//提供Set方法给外部操作,提供get方法给外部访问
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age<0 && age > 150) {
System.out.println("请输入正常的年龄");
}else {
this.age = age;
}
}
public boolean isMan() {//boolean类型的get方法用is替换
return man;
}
public void setMan(boolean man) {
this.man = man;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + ", man=" + man + "]";
}
}
15. 多态
多态指的是同一个方法调用,由于对象不同可能会有不同的行为
多态的要点:
-
多态是方法的多态,不是属性的多态(多态与属性无关)。
2.多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。
-
父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了
Java中存在多态的前提条件:要有继承,方法的重写,父类引用指向之类
成员访问的特点:
成员变量: 编译看左边(父类),运行看左边(父类)
成员方法: 编译看左边(父类),运行看右边(子类)
静态方法: 编译看左边(父类),运行看右边(父类)
总结: 只有非静态的成员方法,编译看左边,运行看右边
public class Demo01 {
public static void main(String[] args) {
Animal a = new Animal();
Animal b = new Dog();//多态 向上转型 : 子类-->父类
Dog b1 = (Dog)b;//向下转型: 父类强制转换成子类
Animal c = new Cat();//多态
animalCry(a);//叫
animalCry(b);//汪汪汪
animalCry(c);//瞄~~~
}
public static void animalCry(Animal a) {
a.shout();//传进来谁就是谁调用
}
}
class Animal{
public void shout() {
System.out.println("叫");
}
}
class Dog extends Animal{
public void shout() {
System.out.println("汪汪汪");
}
}
class Cat extends Animal{
public void shout() {
System.out.println("瞄~~~~");
}
}
16. final关键字
final作用:
1.修饰变量:被他修饰的变量是不可变的,一旦给了值,就不能被重新赋值了
final int MAX_SPEED = 120;
2.修饰方法:该方法不可以被子类重写,但是可以重载
final void study(){}
3.修饰类:修饰的类不能被继承,比如Math,String等
final class A{}
17. 抽象
1.抽象方法
使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
2.抽象类
包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
1.有抽象方法的类只能定义成抽象类
2.抽象类不能实例化,即不能用new来实例化抽象类。
3. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。
4. 抽象类只能用来被继承。
5. 抽象方法必须被子类实现。
public class Demo01 {
public static void main(String[] args) {
}
}
abstract class Person{
abstract public void eat();
abstract public void sheep();
abstract public void work();//抽象方法均没有实现
public void run() {
System.out.println("奔跑吧");
}
}
class Student extends Person{
//所有子类需要实现抽象类里面未实现的方法
@Override
public void eat() {
// TODO Auto-generated method stub
}
@Override
public void sheep() {
// TODO Auto-generated method stub
}
@Override
public void work() {
// TODO Auto-generated method stub
}
}
abstract class Worker extends Person{
//抽象类继承抽象类不需要实现抽象方法,但是它的子类会去实现
}
18.接口
1.接口就是对外提供的访问规则,完全面向规范,规定一些类具有公共的方法,用inerface表示
2.接口不能被实例化,里面都是抽象方法一般按照多态的方式实例化
3.接口的子类可以是抽象类(意义不大)可以是具体类,是重写接口里面的方法
接口和实现类不是父子关系,而是实现规则的关系
类与接口的区别:
类与类: 继承关系,只能是单继承,可以是多继承
类的接口: 实现关系,可以单实现,也可以是多实现
接口与接口:继承关系,可以单继承,也可以是多继承
声明格式:
[访问修饰符] interface 接口名 extends 父类接口1,父类接口2...{
}
class 类名 implements 父类接口1,父类接口2...{
//需要实现接口
}
访问修饰符只能是public 或者默认
接口名和类名采用相同的命名机制
extends:接口可以多继承
常量:接口中的属性只能是常量
方法:接口中的方法只能是:public abstract
子类需要用implements去实现接口中的规范
JDK1.7之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。
JDK1.8后,接口中包含普通的静态方法。
public class Demo01 {
public static void main(String[] args) {
Student stu = new Student();
stu.run();
stu.eat();
stu.call();
Person stu1 = new Student();
stu1.run();
stu1.eat();
}
}
interface Person{
int SIZE = 6; //相当于 public static final int SIZE = 6;
//所有的方法都是抽象的
void run();//public abstract void run()相当于这个
void eat();
}
interface Animal{
void call();//叫
}
interface AquaticLife extends Person,Animal{//水生物
void swim();
}
class Student implements Person,Animal{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("每天早上晨跑" + SIZE+"个人一起");
}
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("从来不吃早餐");
}
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("嬉戏,大吵大闹");
}
}
class Teacher implements Person{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("坚持运动");
}
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("一天三餐");
}
}
class My implements AquaticLife{
@Override
public void run() {
// TODO Auto-generated method stub
}
@Override
public void eat() {
// TODO Auto-generated method stub
}
@Override
public void call() {
// TODO Auto-generated method stub
}
@Override
public void swim() {
// TODO Auto-generated method stub
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8VPiM97-1571964837689)(C:\Users\a4244\Desktop\MD\17.png)]
内部类
Java的内部类主要分为:
- 成员内部类public、default、protected 、private
- 非静态内部类
- 静态内部类
- 匿名内部类
- 局部内部类(变量用final修饰)
- 私有内部类
局部内部类用变量修饰是因为,当调用这个方法的时候,局部变量如果没有用final修饰,它的生命周期和方法是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失的时候,想要用这个变量就不能用了,如果用final修饰就会在类加载的时候进入常量池,即使方法弹栈常量池的常量也还在,也可以继续使用
匿名内部类前提需要抽象类或者接口;
格式:new 抽象类或者接口名(){重写方法}
创建静态内部类对象语法:
外部类名.内部类名 对象名 = 外部类名.内部类名();
创建非静态内部类对象语法:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
package cm.baidu12;
public class Demo01 {
public static void main(String[] args) {
//创建非静态内部类对象
A.B b = new A().new B();
b.show();
//调用内部的静态方法,静态类里面可以有非静态方法和今天方法,非静态类里面不能有静态方法
A.C.run();
//静态内部类不依托外部类,所以实例不需要先创建外部类
A.C c = new A.C();
c.show();
//私有内部类
A a = new A();
a.E();//执行私有内部类方法
Demo01.test01(new AA() {//................接口匿名匿名内部类1
@Override
public void aa() {
// TODO Auto-generated method stub
System.out.println("你吃饭了吗");
}
});
AA aa1 = new AA() {//.....................接口匿名匿名内部类2
@Override
public void aa() {
// TODO Auto-generated method stub
System.out.println("我的AA接口的匿名类");
}
};//.aa() 点aa调用aa的方法
aa1.aa();//两种方法调用
Animal cat = new Animal() {//..............抽象类匿名内部类
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("我已经不跑了,老了");
}
};//.run();调用匿名内部类中的run方法
cat.run();//调用的两种方法都可以,直接在后面点只能调用一个方法,这种的随便调用
}
public static void test01(AA a) {
a.aa();//没有实现
}
}
//内部类的好处就是可以直接访问外部类的方法与属性
class A{//外部类,外部顶级类只能使用public和default修饰。
private static int age = 12;
private String name = "He";
class B{//...............................非静态内部类
int age = 30;
public void show() {
int age = 20;
//外部类属性:外部类.this.变量名
System.out.println(A.this.age);//12 访问外部类的属性,外部类不能访问内部类
//内部类属性:this.变量名
System.out.println(this.age);//30
//内部类里面的方法: 变量名
System.out.println(age);//20
}
}
static class C{//.........................静态内部类
final int age = 100;//局部变量
/*
* 局部内部类访问他所在的方法中的变量必须用fianl修饰,jdk1.8,不加fianl不会报错,之前就会
*
*/
public void show() {
System.out.println("我是静态内部类");
int age = 200;
System.out.println(A.age);//静态只能访问静态
System.out.println(this.age);
System.out.println(age);
}
public static void run() {
System.out.println("我跑的很快");
}
}
private class D{//.........................私有内部类
//访问私有内部类方法,必须在外面创建方法(E)
public void run() {
System.out.println("我在奔跑");
}
}
public void E(){
D d = new D();
d.run();
}
public void F() {//.......................局部内部类
final int f = 10;//用final修饰,不然JDK1.7报错
class G{
public void eat() {
System.out.println(f);//JDK1.7及以下报错,1.8以上没事
}
}
}
}
interface AA {
void aa();
}
class BB implements AA{
@Override
public void aa() {
// TODO Auto-generated method stub
System.out.println("我是aa接口的BB类的方法");
}
}
abstract class Animal{
abstract public void run();
}
class Dog extends Animal{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("你还在跑吗");
}
}
ln("我是静态内部类");
int age = 200;
System.out.println(A.age);//静态只能访问静态
System.out.println(this.age);
System.out.println(age);
}
public static void run() {
System.out.println("我跑的很快");
}
}
private class D{//.........................私有内部类
//访问私有内部类方法,必须在外面创建方法(E)
public void run() {
System.out.println("我在奔跑");
}
}
public void E(){
D d = new D();
d.run();
}
public void F() {//.......................局部内部类
final int f = 10;//用final修饰,不然JDK1.7报错
class G{
public void eat() {
System.out.println(f);//JDK1.7及以下报错,1.8以上没事
}
}
}
}
interface AA {
void aa();
}
class BB implements AA{
@Override
public void aa() {
// TODO Auto-generated method stub
System.out.println("我是aa接口的BB类的方法");
}
}
abstract class Animal{
abstract public void run();
}
class Dog extends Animal{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("你还在跑吗");
}
}