面向对象是相对于面向过程而言的。面向过程注重的是过程,强调的是在完成的这个过程当中的动做。面向对象注重的是对象,只要找到了这个对象,就拥有了这个对象所具备的一切功能。java
好比作饭,若是本身作饭的话,就须要本身准备食材,炊具等等,还要进行烹饪。可是当咱们找到一个餐馆,这些事情就都不需本身作了,就等着吃饭就好了。此时餐馆就至关于一个对象,咱们只要找到了这个餐馆,就拥有了这个餐馆具备的一切功能。sql
面向对象是基于面向过程的。面向对象不必定优于面向过程,若是事物相对简单,适合用面向过程;若是事物比较复杂,适合于面向对象。数据库
根据一类事物进行抽取,将这一类事物用一个类表示,同时将这一类事物的共有特征抽取成属性,将这一类事物的共有行为抽取成了方法。类是对象的抽取/归纳。经过new关键字来产生对应的对象/实例。对象是类的实例化/具体化。数组
好比:人通常都有姓名、性别、年龄等一些特征,还有睡觉等行为。咱们就能够进行以下的操做:安全
public class PersonDemo{ public static void main(String[] args){ Person p = new Person(); p.name = "rose"; p.age = 18; p.gender = '女'; } } calss Person{ String name; int age; char gender; public void sleep(){ System.out.println("sleep !"); } }
对象在内存中的存储以下图:网络
public class PersonDemo{ public static void main(String[] args){ Person p = new Person(); p.name = "翠花"; p.age = 18; p.gender = '女'; changeName(p); System.out.println(p.name); //结果是如花。 } Public void changeName(Person p2){ P2.name = "如花"; } }
注意:对象在传值的时候传递的是地址。上个章节咱们已经强调过。并发
内存调用以下图:ide
在类内方法外的变量叫成员变量。函数
在方法内的变量叫局部变量。高并发
在定义格式上相同。
成员变量是定义在类内方法外;局部变量是定义在方法或者语句内部。
成员变量做用域整个类;局部变量只能在定义的方法或者语句内部使用。
成员变量存在堆内存中,而且在堆内存中自动的赋予默认值;局部变量是存储在栈内存中,不会自动给值,须要手动初始化。
成员变量是随着对象的建立而加载到堆内存中,并获取默认值,随着对象的回收而释放(解析);局部变量在方法或者语句执行的时候建立,随着方法或者语句的结束而当即移除出栈内存。
在类中与类同名,没有返回值,也没有返回值类型的方法,主要是用于建立对象(描述对象建立过程)叫作构造方法,也叫构造函数。
若是一个类没有手动提供构造函数,那么JVM在编译的时候会添加一个无参的构造函数。若是手动添加了构造函数,JVM就不会再提供无参构造函数。
class Person{ public Person(){} }
构造函数在类的对象建立时就运行,一个对象建立后,其构造函数只执行一次,就是建立时执行。父类中必须有一个无参的构造函数,子类中能够有有参的也能够有无参的不用上下对应。
public 类名(参数1,参数2,……){ Code; }
1.构造方法没有返回值类型,也没有返回值。
2.构造方法能够重载。
3.构造方法能够写return语句,为了规避风险。
4.构造方法能够有参数,参数通常是建立对象必须依赖的条件(前提条件)。
5.构造方法能够存在与类同名的普通函数。可是通常不建议使用。
我将这5个特色简单记忆为1个没有,4个能够。
任何一个对象建立时,都须要初始化才能使用,因此任何类想要建立实例对象就必须具备构造函数。标识对象建立的开始和结束。
构造函数能够对对象进行初始化,而且是给与之格式(参数列表)相符合的对象初始化,是具备必定针对性的初始化函数。
this表明当前对象的引用。
注意:在Java中全部的非静态属性和非静态方法都会经过对象来调用的。
this表明当前在使用的对象。
能够认为是一个虚拟对象,能够经过this在本类中调用本类的非静态方法和非静态属性。
this语句表示在本类的构造函数中调用本类的其余的对应形式的构造函数。
this语句会自动匹配对应形式的构造函数。
this语句必须放在构造函数的第一行。
class Person{ public Person(){} public Person(String name,int age){ this.name = name; this.age = age; } public Person(String name,int age,int gender){ this(name,age); //this语句。调用自己的构造函数。 this.gender = gender; } }
1.引用成员变量。
2.调用类的构造方法。
3.返回对象的值。return this;
没有名字的对象(匿名对象其实就是定义对象的简写格式)。
//正常形式 Car c =new Car(); c.run(); //匿名对象形式: new Car().run();
1.当对象对方法仅进行一次调用的时候,就能够简化成匿名对象。
new Person.eat(); new Person.age = 20;
2.匿名对象能够做为实际参数进行传递。
changeAge(new Person);
在函数或者语句内部用{ }括起来的代码块称之为局部代码块,又叫普通代码块。是做用在方法中的代码块。
Public static void main(String[] args){ { Int i = 2; System.out.println(i); } //i 变量被释放。 Int j = 3; System.out.println(j); }
用于限制变量的使用范围和生命周期,从而提升内存的利用率。
直接在类中定义且没有加static关键字的代码块称为构造代码块,也叫初始化代码块。在构造函数执行以前先执行一次。
构造代码块在建立对象时被调用,每次建立对象都会被调用,而且构造代码块的执行次序优先于类构造方法。
执行顺序:(优先级从高到低)静态代码块→main方法→构造代码块→构造方法。
{ 构造代码块执行语句 }
把多个构造方法的共同代码放在一块儿。
构造代码块是给全部对象进行统一初始化,而构造函数是给队形的对象初始化,由于构造函数是能够多个的,运行哪一个构造函数就会创建相应的对象,但不管创建哪一个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不一样对象共性的初始化内容。
面向对象的特征有:封装、继承、多态 (抽象)。
封装是面向对象方法的重要原则,就是把对象的属性和操做(或服务)结合为一个独立的总体,并尽量隐藏对象的内部实现细节。封装是一种信息隐藏技术。
提升了代码的复用性。
属性的私有化属于类的封装,提升了代码的安全性。经过将属性私有化,而后提供对外的公共的访问方法来设置或者获取该属性,能够在方法中对属性的设置或者获取作一系列的限定。
内部类也是封装的一种体现形式。
提升了复用性、安全性、使代码结构更加紧密。
1.使属性私有化---隐藏信息,实现细节。
2.使属性值更符合要求---能够对成员进行更精确的控制。
3.提升了代码的安全性---类内部的结构能够自由修改
4.良好的封装可以减小耦合。
若是一些类中含有相同的属性和方法,那么能够将这些相同的属性和方法提取到一个新的类中,利用extends关键字让原来的类和新的类产生联系,而这个关系称之为继承。新产生的类称之为父类(超类/基类),原来的类称之为子类(派生类)。
父类是子类的通常化,子类是父类的具体化。
注意:Java中支持的使单继承。一个子类只能有一个父类。一个父类能够有多个子类。
子类经过继承父类可使用父类中的一些方法和属性。
calss a{} class B extends A{//B类继承了A类 }
1.继承关系是传递的。
2.继承简化了人们对事物的认识和描述,能清晰的体现相关类间的层次结构关系。
3.继承提供了软件复用功能。
4.继承经过加强一致性来减小模块间的接口和界面,大大增长了程序的易维护性。
5.提供了多重继承机制。经过使用接口机制来实现多重继承。
1.提升复用性。
2.提升安全性。
3.统一结构。
1.子类拥有父类非private的属性和方法。
2.子类能够拥有本身的属性和方法,即子类能够对父类进行扩展。
3.子类能够用本身的方法实现父类的方法。
1.父类变,子类就必须变。
2.继承破坏了封装,对于父类而言,它的实现细节对于子类来讲都是透明的。
3.继承是一种强耦合关系。
1.多继承在代码的复用性上要优于单继承,可是存在方法调用的混乱。
class A{ public int m(){ return 2; } } class B { public int m(){ return 1; } } public class C extends A, B{ C c = new C(); int i = c.m(); // 多继承会产生方法调用的混乱 }
2.单继承也能够提升代码的复用性,能够避免方法调用的混乱,提升了方法调用的安全性。
权限修饰符用于限定变量或者方法的使用范围。
修饰符的控制范围:
|
本类中 |
同包类中 |
子类中 |
其余类中 |
Public(公共的) |
能够 |
能够 |
能够 |
能够 |
Protected(受保护的) |
能够 |
能够 |
能够 |
不能够 |
默认 |
能够 |
能够 |
同包子类能够 |
不能够 |
Private(私有) |
能够 |
不能够 |
不能够 |
不能够 |
权限修饰符的控制范围从定义的位置上看起。
package cn.a; import cn.a.A; public class extends A{ public static void main(String[] args){ B b =new B(); b.m();//m方法使属于b对象,m方法没有在对象对应的子类中用。 } }
在建立子类对象的时候,会先建立一个父类对象,而这个父类对象在子类中以super关键字的形式存在。super是父类对象的引用。
super表示在子类中表明了父类的对象。经过super来调用父类中的方法或者属性。能够将super当作一个虚拟对象。
在子类构造函数中经过调用父类对应形式的构造函数。
若是子类构造函数中没有手动添加,那么JVM在编译的时候会自动添加一个无参的super();。
调用super语句的时候,会自动匹配父类中对应形式的构造函数。
若是父类中没有提供无参构造函数,则默认省略的super语句就不能使用,那么这个时候子类的构造函数中须要手动添加一个super语句,super语句必须放在子类构造函数的首行。
this语句和super语句不能同时使用,若是子类的构造函数中已经存在来this语句,它会调用自己的其余含有super语句的的构造函数,来建立父类。
子类的构造函数中必然直接或者简介的有一个super语句,在建立子类对象的时候必然先建立一个父类对象。
能够经过this来调用父类中的方法或者属性。
// 父类 class Pet { String species; int age; public Pet(int age) { this.age = age; } public Pet(String species, int age){ } public void eat() { System.out.println("在吃食~~~"); } } // 经过extends关键字产生的联系---继承 // 子类 class Cat extends Pet { public Cat(){ // super语句必须放在构造函数的首行 super(5); } // 方法的重写/覆盖 @Override // 注解---这个注解用于标识这个方法是一个重写的方法 public void eat() { System.out.println("猫在吃土~~~"); } } class Dog extends Pet { public Dog() { // super语句---表示调用了父类的无参构造 // super(); super(5); } public void sleep() { // super 表明一个父类对象---在子类中调用父类中的方法或者属性 super.eat(); System.out.println("吃饱以后开始睡觉~~~"); } }
1.super.成员变量/super.成员方法;
用来在子类中调用父类的同名成员变量或者方法。
2.super(parameter1,parameter2……);
用在子类的构造器中显示调用父类的构造器。
1.构造方法。
2.用private修饰的东西,即全部私有的东西。
3.构造代码块和静态代码块。
4.默认权限不一样包的东西。
多态是指容许不一样类的对象对同一消息作出响应。即同一消息能够根据发送对象的不一样而采用多种不一样的行为方式。多态主要针对对象的行为即方法,而不是对象的属性。
实现多态的技术称为动态绑定,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
下降模块与模块之间的依赖性就是解耦。
多态的产生使为了解耦,消除类型之间的耦合关系。
1.要有继承。
2.要有重写。
3.父类引用指向子类对象。
1.可替换性(substitutability)。多态对已经存在代码具备可替换性。
2.可扩充性(extensibility)。多态对代码具备可扩充性。
3.接口性(interface-ability)。
4.灵活性(flexibility)。在应用中体现了灵活多向的操做,提升了使用效率。配合反射实现解耦。
5.简化性(simplictiy)。多态简化对应用软件的代码编写和修改过程,尤为在处理大量对象的运算和操做时,这个特色尤其突出和重要。
在编译时期就要动态绑定的运行过程。例如:方法的重载。
add(1,2) add(1,2,3) //编译时期就能肯定要使用的方法。
在运行时期才能肯定绑定的运行过程。例如:向上造型、方法的重写。
继承是运行时多态的前提。
①向上造型
1)定义
用父类声明的,用子类来建立实际对象叫向上造型。
子类的对象能够向上造型为父类的类型。即父类引用子类对象,这种方式被称为向上造型。
使用向上造型声明的对象可使用父类中的全部,可是只能使用子类中,父子类共有的东西。
当向上造型建立对象的时候,用父类声明,用子类建立,父类在声明的时候就至关于给来这个对象一份提纲;子类建立对象的时候是告诉来对象该怎么干。
当用向上造型来建立对象的时候,对象可以干什么,看的是父类。行为应该怎么干,看的是子类。
当用向上造型来建立对象的时候,在编译的时候只检查两个类之间是不是继承关系,而不去具体检查是用哪一个类来建立的对象,在运行时期才会检查是谁来建立的对象。因此,向上造型使运行使多态。
②方法的重写
当调用方法的时候,调用的是重写以后的方法。
在编译的时候只须要检查这个声明的类中是否包含指定的方法,在运行的时候才绑定子类中的具体的方法。父类强转换为子类会出现ClassCastExcepion(类转换异常)。
向上造型
重写和重载
static自己是一个修饰符,能够修饰变量、方法、内部类、代码块。静态是从类的层面来看的,已经超越了对象。
标记一个方法为static,意味着这个方法被所在类的全部实例公用,在类装载时初始化,被全部该类的实例共享,同时意味着:
1.static方法内部不能声明static变量。
2.Static方法不能被子类重写为非static方法。
3.父类的非static方法不能被子类重写为static方法。
4.Static代码块能够用static{}来完成,在类被第一次装载时执行初始化,先于静态方法和其余方法的执行。
程序启动的时候先经过类加载器(ClassLoader)将基本核心类库(java.long包)加载到方法区,其次是主函数所在的类加载到方法区。
加载主函数所在的类。首先将Java源文件编译为class文件,而后class文件经过类加载器(ClassLoader)将class文件加载到方法区当中。将StaticDemo1.class存放到方法区中,将主函数main存放到方法区的静态区中。
当执行语句Person p1 = new Person(); 时,会将Person类的java源文件编译成class文件,而后将class文件经过类加载器(ClassLoader)将class文件加载到方法区中。在静态常量池中开辟空间,将Person.class以及其包含的内容存放在静态常量池,而后在静态区中开辟空间,将Person.class中的静态属性以及静态方法存放到静态区中,并给静态属性变量赋予默认值(gender = ‘\u0000’)和方法区空间地址(0x02da)。以上工做完成以后,会在栈内存中声明一个对象p1。而后执行new Person,在堆内存中开辟空间存储p1对象的一系列属性(name,age,gender),并赋予默认值(name = null;age=0;gender = 0x02da;由于gender为静态变量因此gender的默认值是方法区中对应静态变量的空间地址)和堆内存空间地址(0x6f8d),而后将堆空间地址赋值给栈内存中对应的对象。
当执行p1.name = “张无忌”;时,对象p1会沿着p1对象中存储的堆内存空间地址找到本身的属性,给本身的name属性赋值为:张无忌,将默认值覆盖。p1.age = 81;也是如此。
当执行p1.gender = ‘男’;时,对象p1会沿着p1对象中存储的堆内存空间地址找到本身的属性gender,而后沿着gender中存储的方法区空间地址找到方法区中静态区里的gender,而后给静态区里的gender赋值为:男。
当执行语句Person p2 = new Person();时,由于全部的类已经加载过了,因此能够直接进行声明和初始化操做。栈内存和堆内存中的操做和语句Person p1 = new Person();是同样的。
当执行语句p2.name = “赵敏”; p2.age = 18 ; 过程和p1.name = “张无忌”; p1.age = 81 ; 是同样的。
当执行p2.gender = ‘女’;时,对象p2会沿着p2对象中存储的堆空间地址找到堆内存中p2对应的gender属性,而后在根据gender属性中存放的地址找到方法区中静态区里的gender变量并赋值为:女,将原来的“男”值替换掉。因为p1和p2中gender属性存储的方法区空间地址是同样的,因此咱们能够认为p1.gender = p2.gender = ‘女’;。
当执行语句p1.eat();时,p1对象会调用方法区中静态常量池里Person.class的eat();方法,Person.class会给出eat()方法的地址,而后入栈,在栈内存中开辟空间执行eat();方法,eat();方法中会自动产生this关键字表明p1对象,此时this 中存储的使p1中存储的堆内存空间地址,而后输出方法的结果。
static修饰变量那么这个变量咱们就称之为静态变量,又称为成员变量或者类变量。
静态变量随着类的加载而加载到了方法区中的静态区,而且在静态区中自动赋予了一个默认值。静态变量先于对象而存在,因此静态变量能够经过类名来调用,也能够经过对象来调用。该类产生的全部的对象实际上存的是该静态变量在静态区中的地址,静态变量是被全部对象所共享的。
例如:System.in; System.out; 都是静态变量。
1.静态变量有默认值。
2.静态变量能够被类调用,也能够被对象调用。
3.静态变量是被全部对象共享的。
4.静态变量可使用this来调用。
5.静态变量不能定义到构造代码块中,但能够在构造代码块中对静态变量赋值。
6.静态变量不能定义到方法中。静态变量在加载的时候就须要分配空间,而方法在加载的时候不须要空间,在执行的时候才须要内存空间。
注意:实际开发中,static能少用就少用。
1.在语法定义上的区别。静态变量前要加static关键字,而实例变量前则不加。
2.在程序运行时的区别。实例变量属于某个对象,必须建立对象才能使用。静态变量则能够直接使用类名引用。
static修饰方法就叫静态方法,也叫类方法。
Arrays.sort()、Arrays.toString()、Arrays.copyOf()、System.arraycopy()都是静态方法。
在类加载的时候加载到了方法区中的静态区,只是存储在静态区,在方法被调用的时候到栈内存中执行。静态区中的元素不归属于某一个对象而是归属于类。静态方法先于对象而存在的,因此静态方法能够经过类名来调用,也能够经过对象来调用。
1.静态方法中不能定义静态变量,但能够对静态变量赋值。
2.不能在静态方法中直接调用本类中的非静态方法。能够经过建立对象来调用。全部非静态的方法和变量都须要对象来调用。
3.静态方法中不能使用this或者super。(主函数是静态方法)
4.静态方法能够重载。
5.静态方法不能够重写。但父子类中能够出现方法签名一致的静态方法,好比:main主函数。若是父子类中出现了两个方法签名的一致的方法要么全是静态,要么全是非静态。
6.静态方法能够被继承。
静态不属于对象。而是属于类。不依赖某个对象而存在,而是依赖于类存在的。类没有多态,多态针对的是方法
注意:类只加载一次,是在第一次使用的时候才加载到方法区,并且加载到方法区中以后就再也不移除了。
在类中成员的位置用static修饰用{}括起来的代码块。
静态代码块针对的是类,因此也能够叫作类代码块。
实际上静态代码块是随着类的加载而加载到静态区,在类建立对象或者执行方法以前执行一次,终其一辈子只执行一次。
通常是对类进行初始化。
在这个类第一次被真正使用(第一次建立对象/调用方法)的时候执行一次。若是一个类包含多个静态代码块,则按照书写顺序执行。因为类只在第一次使用的时候加载,因此静态代码块也只执行一次。
代码执行顺序:先父类后子类,先静态后动态。(先父子类的静态,后父子类的动态)静态优先,父类优先。
代码是从上到下,从左到右依次编译执行。
建立子类对象的时候须要先建立父类对象→加载父类→执行父类静态代码块→执行子类代码块→父类构造代码块→父类构造函数→子类构造代码块→子类构造函数
final能够修饰数据,方法以及类。
当final修饰数据(基本类型和引用类型)的时候,表示这个变量的值不可变,称之为常量。终其一辈子只能赋值一次。
在Java中所说的常量每每是指静态常量。由于实质上只有静态常量才是独有的一个。
System.in/out in和out都是静态常量。NaN和infinity也是静态常量。
arr.length length是个常量。
1.常量在定义好以后不可改变,final固定的是栈内存中的数值。
public class Demo { private final int i; public Demo(){ this(5); } public Demo(int i){ this.i = i; } } Demo d = new Demo(5);
2.常量能够做为参数传递。
3.对引用类型而言,final固定的是其在栈中的地址不可变。
数组在栈内存中存储的是地址,用final修饰,是不能改变数组的地址,但数组的值能够改变。对于对象而言,对象的引用不能改变,可是引用的属性值是能够进行改变的。
4.成员常量只要是在对象建立完成以前(构造方法/函数执行结束以前)赋初始值便可。
5.静态成员常量(static final)只要在类加载完成以前给值便可,并且只能在静态代码块中赋值。
final修饰方法的时候,这个方法就是最终方法。
1.最终方法不能够被重写,能够重载,能够被继承。
2.静态方法能够被final修饰。
final修饰类那么这个类就是最终类。
1.最终类不能够被继承,也不能有匿名内部类形式。
2.现阶段最终类的方法不能被重写。
System 、String是最终类。
abstract class Pet{ public abstract void eat(); } class cat extends pet{ public void eat(){ System.out.println("这只猫在吃鱼……") } }
若是全部的子类中存在了一些名称一致而细节不一样的方法的时候,这个时候能够在父类中声明该行为,此时声明行为的时候不须要添加方法体,因此此时该方法就造成了抽象方法,使用abstract修饰。
1.抽象方法能够和抽象方法重载,也能够和实体方法重载。
2.抽象方法没有方法体。
1.抽象方法不能够被static、final、private修饰,由于final和private修饰符修饰的方法都不能够被重写;static修饰的方法,先于对象存在,没有具体对象没办法加载。
2.抽象方法可使用默认权限修饰,要求子类必须和父类同包。
3.抽象方法能够被protected权限修饰,要求要么同包要么是子类。
将一些名称一致可是细节不一样的行为提取到父类中定义为抽象方法,抽象方法所在的类就是抽象类,用abstract来修饰的类。抽象类中,不必定含有抽象方法,可是抽象方法所在的类必定是抽象类。
1.抽象类不能够在Java中建立对象/实例化。即便没有抽象方法也没法建立对象,能够建立匿名内部类。
2.抽象类有构造方法。抽象类的构造方法能够私有化,在本类中使用。能够建立对象,在底层用C语言建立对象。抽象类的构造方法一旦被私有化,就不能被继承了。
3.抽象类被子类继承以后,必须重写其中的抽象方法。子类若是也为抽象类,能够不重写。抽象方法必然会被重写。
4.抽象类中能够没有抽象方法。抽象类中能够定义一切的属性和方法。
5.抽象方法不能有方法体,()以后直接以;结尾。
抽象类不能用final修饰。最终类不能够是抽象类。
限制规定子类必须实现某些方法,但不关注实现细节。
抽象类和普通类的区别就是能够有抽象方法,不能够建立对象。
用interface来声明,全部方法都为抽象方法那么咱们就称之为接口。经过implements关键字让接口和类产生联系,这个过程叫实现。在接口中使用向上造型来建立对象,就是接口的多态。
interface Pet{ void eat(); } public class Mouse implements Pet{ public void eat(){} }
1.接口中方法的abstract关键字能够省略。
2.类用implements来实现一个接口。必须实现这个接口中全部的方法。
3.因为接口中都是抽象方法,接口不能实例化。
4.接口中没有构造函数。虽然接口在编译完成以后会产生class文件,可是接口不是类。
5.接口中能够定义属性,这个属性默认是一个静态常量。
1.接口中的属性默认是用public static final 来修饰,修饰符的位置能够互换。
2.接口中的方法默认用public abstract修饰,并且只能是public修饰的,public能够省略不写。在接口的子类中实现接口的方法记得用public修饰。
interface A { void m(); // 默认是public修饰 } public class B implements A { void m(){} // 须要添加修饰符public }
Java中类支持单继承,多实现。一个类只能继承一个类,可是一个类能够实现多个接口。一旦出现了多实现,那就必不可免的会致使方法调用混乱。
interface Pet{ Void eat(); } interface Animal{ Void play(); } public class Mouse implements Pet,Animal{ public void eat(){} public void play(){} }
Java中接口之间是多继承,而且接口和类之间是多实现的关系,因此就造成了一张继承关系网,因为在网状结构中寻找一个根节点比较困难,为了提升效率,Java在编译的时候放弃检查接口和类之间是否有实现关系。
当类进行强制转换的时候,JVM在编译的时候会对两个类进行检查,检查这两个类之间是否有继承关系。若是有继承关系,则编译的时候会经过,可是运行的时候不必定正确。若是没有继承关系,则在编译的时候直接报错。
统一告终构。接口能够做为模板,配合多态实现解耦,好比:反射。
定义在类或者接口中的类就称之为内部类。内部类是封装的第三种形式。
内部类根据使用的位置和修饰符不一样分为:方法内部类、成员内部类、静态内部类、匿名内部类。
除了静态内部类,其他的内部类中都不容许定义静态属性和静态方法,可是能够定义静态常量。
除了静态内部类,其他的内部类均可以使用当前外部类的属性和方法,可是静态内部类只能使用外部类的静态成员。
定义在方法中的类叫作方法内部类。
class Outer1{ public void m(){ class Inner1{ public void m(){ System.out.println(“inner1 m”); } } Inner i1 = new Inner1(); i1.m(); System.out.println(“outer1 m”); } }
1.方法内部类在哪定义在哪使用。除了当前的方法,其他地方不能使用。
2.方法内部类优先于当前方法加载。
3.方法内部类不容许使用当前方法的局部变量。可使用当前方法的常量。在JDK1.8中常量不用显式声明常量,可是本质上依然是一个常量。
4.方法内部类可使用外部类的一切属性。
5.方法内部类中能够定义成员方法、成员属性和静态常量,可是不能定义静态方法和静态属性。
为何要定义方法内部类?
方法内部类是为了私有本类方法中的参数。内部类能够继承能够实现。
定义在类内方法外的类叫作成员内部类。也就是成员变量的位置。利用外部类对象来建立成员内部类对象。
public class InnerClassDemo { public static void main(String[] args) { new Outer2().new Inner2().m(); //利用外部类对象来建立成员内部类对象 } } class Outer2{ int i=5; class Inner2{ public void m(){ System.out.println("inner2 m"); } } }
1.成员内部类能够定义普通的方法和属性,可是依然不能定义静态方法和静态属性。
2.成员内部类能够定义静态常量。
3.成员内部类可使用外部类中的一切方法和属性。
4.成员内部类可使用权限修饰符修饰内部类。
5.成员内部类能够建立对象。
Java底层集合和映射用的比较多。有一系列对象,而这些对象对外不可见,就能够用成员内部类。
用static修饰的成员内部类叫作静态内部类。能够直接利用外部类来建立静态内部类的对象。
1.能够定义一切的属性和实体方法。
2.静态内部类只能使用外部类中的静态属性和静态方法。非静态的属性和方法不可用。
3.可使用权限修饰符修饰。
没有名字的内部类叫作匿名内部类。包含成员匿名内部类,方法匿名内部类。
1.匿名内部类本质上是继承了对应的类或者是实现了对应的接口。
2.只要一个类能够被继承,那么这个类就能够出现匿名内部类的形式。当利用一个类来建立一个匿名内部类的时候,实际上这个匿名匿名内部类是继承了这个类。
3.匿名内部类有构造函数,可是不能手动添加构造方法。
当利用匿名内部类来建立对象的时候,要求这个匿名内部类必须实现父类中的全部抽象方法。
Demo demo = new Demo() {//声明一个匿名内部类 @Override public void m() { } }; // 匿名内部类本质上是实现了这个接口 A a = new A() { }; // B b = new B() { // }; }
4.若是匿名内部类定义到了方法中,此时匿名内部类的使用规则和方法内部类一致。
5.若是匿名内部类定义到了类中,此时匿名内部类的使用规则和成员内部类一致。
定义在类或者接口中的接口叫作内部接口。
类中定义的接口、接口中定义的类或者是接口默认都是用static修饰。
接口必然要被实现,若是内部接口不是静态的,这个时候就须要一个外部类对象来调用接口,而在声明类实现这个接口的时候,没法建立对象,没法建立对象就没法实现了。
package cn.tedu.innerclass; public class InnerDemo2 implements Outer1.Inner1 { @SuppressWarnings("unused") public static void main(String[] args) { Outer2.Inner2 oi2 = new Outer2.Inner2(); } } class Outer1 { // 内部接口 // 这个接口默认是用static修饰 interface Inner1 { } } interface Outer2 { // 内部类 // 默认是用static修饰 class Inner2 { } interface Inner3 { } }
声明包用的package,包的产生是为了解决同名文件的问题。
声明格式以下:
package m.n.c
一个Java文件中只容许存在一个package语句,并且这个package语句必须放在整个Java文件的首行。
导入包用的是import。
import java.util.* //表示导入util包下的全部的类而不包括子包下的类。 //*是一个通配符。
java.lang:核心包(核心类库),在程序启动的时候就已经加载到了方法区中了,在使用的时候不须要导包。
java.util —— 工具包,存放了一系列简化操做的工具类。
java.io —— 数据传输。
java.nio —— 高并发。
java.net —— 网络传输。
java.math —— 数学运算。
java.sql —— 数据库。
java.awt —— 图形用户界面。(几乎不用)
java.security —— 数据安全。
java.text —— 格式化。
javax.* —— 扩展包。
org.* —— 第三方厂商和开源社区提供的包。
同包类和java.lang包不用写导包语句。
注意:包名不能以java,javax,org开头
以上为我的学习整理的笔记和心得,于你们分享,但愿你们多批评斧正。
上一篇:JAVA基础知识