复习
一.static
静态的意思,一个成员修饰符,修饰类中的成员变量或方法。
修饰变量:
1.修饰后的变量:类变量或静态变量
2.类一加载,静态变量就存储到内存中的方法区,随着类的加载而加载,随着类的消失而消失。
3.访问方式:类名.静态变量名 或者通过对象名.静态变量名
4.优先于对象存储在内存中
5.被所有对象所共享
注意:该类所有对象的共享资源数据,如:country…
修饰方法:
1.静态方法或类方法
2.通过类名可以直接访问,或通过对象名去访问
3.静态方法中只能直接使用静态资源,非静态方法中既可以直接操作静态资源也可以直接操作非静态资源
4.静态方法中不能直接使用this或super关键字
注意:类中没有需要维护的属性数据时(即类中没有属性)时,方法设计为静态方法,直接通过类名去访问。
静态方法和成员变量区别:
1.生命周期 2.存储位置 3.访问方式 4.称呼上
二.继承
类和类产生关系,继承关系。
extends:继承
修饰符 class 子类名 extends 父类名{}
好处:1.提高了代码的复用性 2.引出第三特征—多态
弊端:增强了耦合度
特点:
单继承,多层继承(形成了一个继承体系,类似于家谱),Object类。
注意:
is—>a关系 学生 —> 人 猫—>动物
继承出现类中成员的变化:
变量: 就近原则。
方法:
方法重写(覆盖): 子类中重写父类中的方法。
super: 代表父类的引用,只能访问父类中的成员。
this:代表当前类的对象引用,可以访问子类也可以访问父类。
课程
一. 代码块
(一)概述
1、使用大括号包起来的一段代码。放在不同的位置,有不同的名称,有不同的作用,有不同的执行时机。
2、分类:
局部代码块
构造代码块
静态代码块
同步代码块(多线程)
(二)局部代码块
1、位置:定义在方法中的代码块
2、作用:
限定变量的生命周期
在局部代码块中【声明】的变量,只能在局部代码块的范围内使用,一旦出了局部代码块的大括号,变量就不能继续使用了。
缩短局部变量的生命周期,及时的释放内存空间提升代码的运行效率
3、注意事项:
(1) 代码块可以使用外部的所有资源
(2) 如果是在局部代码块中修改了局部代码块外声明的变量,局部代码块结束之后,并不会消除局部代码块对这个变量的修改。
public class Demo3 {
public static void main(String[] args) {
int x = 10; //局部变量 作用域:整个main方法中
//局部代码块
{
int m = 20;
/*for (int i = 0; i <10; i++)
System.out.println(i);*/
x = 100;
}
//System.out.println(m); //m只能在局部块中使用,除了块,m已经被释放了,因此不可以再使用
System.out.println(x); //100
{ //局部代码块
int n = 10;
{ // 局部代码块
int z = 10;
System.out.println(z);
}
//System.out.println(z);
}
}
}
(三)构造代码块
1、位置:定义在类中方法外 【成员变量位置】
2、作用:
(1) 创建对象的时候给对象的属性值显性赋值
(2) 提取本类构造方法中的共性内容实现
3、构造代码块的执行说明:
1、在创建对象的时候执行,由jvm默认调用
2、在构造方法执行之前,执行
public class Demo4 {
public static void main(String[] args) {
new ConstructorCode();
new ConstructorCode(5);//匿名
}
}
class ConstructorCode{
String name;
{
System.out.println("构造块---2");
}
public ConstructorCode(){
System.out.println("构造方法");
}
public ConstructorCode(int x){
System.out.println("构造方法----"+x);
}
//构造代码块
{
System.out.println("构造代码块----");
/*
* 创建对象时执行,并且优先于构造方法执行
* 用于给当前类的所有对象进行统一初始化
*
* 一个类中,可以定义多个构造块,执行是从上到下依次执行,一定是优先于构造方法。
* */
}
}
(四)静态代码块
1、格式:
static {
静态代码块的内容
}
2、位置:类中方法外
3、作用:
(1) 给类的静态变量赋值
(2) 用来加载只需要加载一次的资源【例如: 加载数据库驱动】
4、执行特点:
(1) 随着类的加载而执行
(2) 静态代码块只执行一次
(3) 执行的时机最早:早于所有的对象相关内容
public class Demo5 {
public static void main(String[] args) {
// new StaticCode(); 匿名只执行一次
new StaticCode();
StaticCode sc = null;
/*sc.num = 200; 指向空地址,调用会报错,不调用不显示*/
}
}
class StaticCode{
int num = 100;
static{
System.out.println("静态块");
/*
* 随着类的加载而执行,类只加载1次,因此静态也只执行1次。
* 作用:
* 1.给静态变量初始化
* 2.仅需要加载1次的资源,如加载数据库驱动
*
* 注意: 一个类中可以有多个静态块,执行是从上到下依次执行。
* */
}
static {
System.out.println("静态块---2");
}
}
public class Demo6 {
static {
System.out.println("E");//跟随类执行 第一个
}
{
System.out.println("F");// 没有对象不执行
}
public static void main(String[] args) {
new Demo();
}
}
class Demo extends A{
static {
System.out.println("A");//父类执行完之后子类执行,跟随子类执行
}
{
System.out.println("B");//调用对象之后的执行,父类执行完后,子类的构造块和方法执行
}
public Demo(){
System.out.println("C");//方法执行
}
}
class A{
static {
System.out.println("PP");//父类先执行,跟随父类执行
}
{
System.out.println("OO");//调用对象之后的执行,也是父类先执行,构造块和方法执行
}
public A(){
System.out.println("UU");//方法执行
}
}
/*
E
PP
A
OO
UU
B
C
*/
二. 内部类
(一) 概述
-
定义在一个类中的另一个类就叫做内部类
举例:在一个类A的内部定义一个类B,类B就被称为内部类 -
格式:
public class Outer { // 外部类 public class Inner { }// 内部类 }
-
分类: 根据定义的位置不一样以及是否有名分为了不同的内部类,具体分类如下:
- 成员内部类
- 局部内部类
- 匿名内部类
-
访问特点:
内部类可以直接访问外部类的成员,包括私有成员
外部类要访问内部类的成员,必须创建对象
(二) 普通成员内部类
-
定义位置: 在类中方法外,跟成员变量是一个位置
-
外界创建成员内部类格式
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
举例:Outer.Inner oi = new Outer().new Inner(); -
访问方式:
(1) 内部类可以直接访问外部类的所有成员,包括私有成员
(2) 外部类访问内部类的成员,必须先创建内部类对象
(三) 私有的成员内部类
1、也是一个成员内部类,在成员内部类前面加上一个private关键字
2、访问方式:
(1) 在外部类以外,不能直接访问外部类中的私有成员内部类
(2) 可以在外部类中,定义一个访问私有成员内部类的公有方法,让外界可以调用公有方法,间接的访问外部类中的私有成员内部类。
(四) 静态的成员内部类
1、也是一个成员内部类,在成员内部类前面加上一个static关键字
2、访问方式:
(1) 成员内部类是外部类的静态成员,所以可以通过外部类名.内部类名的方式直接访问,而不需要创建外部类的对象
(2) 静态内部类中的非静态成员,需要将所在的内部类对象创建出来之后,才能被调用。
总结:一个类是否需要创建对象,不取决于该类本身是否是静态,而取决于要访问 的成员是否是静态
3、静态成员内部类的对象创建格式:
外部类名.内部类名 内部类对象名 = new 外部类名.内部类名();
public class Demo7 {
public static void main(String[] args) {
//创建外部类对象
Outer outer = new Outer();
outer.function();
System.out.println("--------------------------------------------");
//直接方式---内部类对象
Outer.Inner inner = new Outer().new Inner();
/*System.out.println(inner.a);
inner.fun();*/
inner.test();
}
}
/*
* 普通的成员内部类:
* 类中成员: 非静态变量或方法。
* 可以直接访问它所属的外部类中的所有成员,包括私有
* 访问内部类中的成员:必须创建内部类对象。
*
* 私有成员内部类:
* 与普通成员内部类用法是相同的。
* 但是有一个区别:
* 只能在内部类所属的外部类中 创建内部类对象, 调用内部类成员
* 不能在外部其他类中直接创建内部类对象。
* */
class Outer{ //外部类
private int x = 10;
static int y = 100;
int m = 1000;
public void show(){
System.out.println("show");
}
public static void method(){
System.out.println("method");
}
class Inner{ //内部类
int a = 20;
int m = 100;
static final int NUM = 100; //常量
public void test(){
int m = 10;
System.out.println(m); //10
System.out.println(this.m);//100
System.out.println(Outer.this.m); //1000,内部类持有它所属的外部类的引用
}
public void fun(){
System.out.println("fun");
System.out.println(x);
System.out.println(y);
show();
method();
}
}
//单独创建方法,在方法中创建内部类对象,通过这个对象访问内部类中的成员
public void function(){
//创建内部类对象
Inner inner = new Inner();
System.out.println(inner.a);
inner.fun();
/*
* 内部类:
* 将一个类定义到另一个类的里边,里边的类叫做内部类。
* 什么时候使用内类形式解决问题?
* 类:用来描述一类事物的。
* 描述的两类事物间,是包含关系。例如: 教学楼--->教室 身体--->心脏...
*
*类中的位置:
* 成员位置和局部位置,因此内部类可以分为:成员内部类和局部内部类
* 成员内部类:可以使用成员修饰符进行修饰, private public static 默认
* 内部类可以没有类名: 匿名内部类。
* */
}
}
```java
import java.util.zip.Inflater;
public class Demo8 {
public static void main(String[] args) {
//创建外部类对象
Outer1 outer1 = new Outer1();
outer1.function();
System.out.println("----------------------------------------");
Outer1.Inner1.fun(); //静态方法
new Outer1.Inner1().show(); //非静态方法
}
}
/*
* 静态内部类:
* static class 类名{
* }
* 成员有: 静态成员 非静态成员
* 可以直接访问它所属的外部类中的成员:静态成员。
* */
class Outer1{
private int x = 10;
static int y = 100;
public void info(){
System.out.println("info");
}
public static void method(){
System.out.println("method");
}
static class Inner1{
int a = 10;
static int b = 10;
static final int NUM = 100; //常量
public static void fun(){
System.out.println("fun");
System.out.println(y);
method();
/* System.out.println(new Outer1().x);
info();*/
}
public void show(){
System.out.println("show");
/*System.out.println(x);*/
System.out.println(y);
}
}
//间接访问,访问内部类中的成员
public void function(){
Inner1.fun(); //静态方法
new Inner1().show(); //非静态方法
}
}
(五) 局部内部类
- 定义位置: 局部内部类是定义在方法中的类
- 访问方式:
(1) 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
(2) 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
public class Demo9 {
public static void main(String[] args) {
Outer2 outer2 = new Outer2();
outer2.method();
}
}
/*
* 局部内部类:
* 内部类定义方法中,这个类不能使用成员修饰符进行修饰。
* 类中成员: 非静态成员
* 可以直接访问它所属的外部类中的所有成员,包括私有(静态和非静态)
* 也可以直接访问它所属的局部位置上的变量,但是这个变量的值不能修改。
* 想要访问局部内部类中的成员,必须创建内部类对象,只能在它所在的局部位置创建。
* */
class Outer2{
private int a = 10;
static int b = 100;
public void info(){
System.out.println("info");
}
public static void fun(){
System.out.println("method");
}
public void method(){
final int num = 100;
class Inner2{ //局部内部类
int x = 10;
static final int NUM = 100; //常量
public void show(){
System.out.println("show");
System.out.println(num);
System.out.println(a);
System.out.println(b);
/* num = 100;*/
}
}
//创建内部类对象
Inner2 inner2 = new Inner2();
inner2.show();
System.out.println(inner2.x);
}
}
三. final关键字
1、final是一个关键字 含义:最终的,最后的,表示不能再改变的。
2、final关键字:可以修饰类、方法、变量
3、修饰类:
(1) 表示一个最终类,表示不能有子类,【不能被其他类继承】
(2) 一旦一个类型不能被继承,那么其中所有的方法都不能被重写
(3) 不影响当前类的方法被调用
4、修饰方法:
表示一个最终方法,【该方法不能被重写】
5、修饰变量:
(1) 表示一个最终变量,该【变量变成了常量】,就只能赋值一次
(2) 当前项目中,常用的常量一般都定义在一个类的成员位置,甚至专门定义一个常量类,常量命名规范: 所有单词全大写, 多个单词之间使用_进行分隔了,举例: SCHOOL_NAME PI
(3) 定义常量的好处:见名知意,容易理解;可维护性高
public class Demo10 {
private final static int x = 0;
final int x = 20;// 非静态下方不调用
public static void main(String[] args) {
//x = 100; 提示final,无法赋值
}
}
/*
* 常量:
* 1.字面值数据 “abc” 123...
* 2.符号常量 给不可变的数据起一个名字,常量名
* 规范:XXX XXX_YYY_ZZZ
* 规范:
* 权限修饰符 static final 数据类型 常量名 = 数值;
* eg: public static final double MY_PI = 3.14;
* */
四. 包
-
包的概述: 用来统一分类管理源代码资源的特殊文件夹;这个文件夹会参与编译。
比如:
com.ujiuye.demo 下的 Person类进行编译的时候类所在的包参与编译,编译后
字节码文件名:com.ujiuye.demo.Person
字节码文件中类名:com.ujiuye.demo.Person【全限定类名】 -
作用:
(1) 统一管理代码资源
(2) 保证代码编译后类名唯一
(3) 保证代码运行的过程直接进入包找到对应的类 -
命名规则:
(1) 使用公司域名的反写【保证每一个包路径唯一】
(2) 全部小写
(3) 包名和包名之间使用.隔开 -
包的声明:
使用关键字 package + 包路径【IDE生成类的时候自动声明】 -
导包:
同包下:不需要导包
不同包:需要导包【jdk的lang包除外】
使用 import + 包路径 -
注意:
(1) 没有导包格式之前:使用类的时候不导包的直接使用全限定类名进行使用
比如:java.util.Scanner sc = new java.util.Scanner(System.in);
(2) 使用全限定类名使用类的时候,有点麻烦进行了简化:
使用import关键字进行提取导包进行导包
(3) 作用
可以把同名字的类使用包做一个详细的划分
package com.day09;
import com.a.Demo3;
public class Demo1 extends Demo3 {
public void a(){
method();
}
}
/*
* package:
* 关键字,用来定义包。
* 包:理解为是文件夹。
* 含义: 告诉编译器当前类要存储在哪个地方。
* package 包名;
* 该语句必须放在代码文件中的有效代码的第一行,而且只能出现一次。
* 一旦定义了包,那么类名的完整形式: 就是包名.类名。
* 包名:
* 公司域名倒置.项目名.模块名.[模快名]*;
* com.ujiuye.cms.login;
* 带包编译:
* javac -d 目录 源文件名.java
* 带包执行:
* java 包名.类名。
*
* import:
* 导入的意思。导入指定包下的类。 目的:简化类名的编写,省略了包名.
* import 语句必须写在 package 和 class 的中间,可以多出现多次。
* 写法:
* import 包名.类名; 导入的是指定包下的指定类
* import 包名.*; 导入指定包下的所有类
*
* jvm启动的时候 默认导入的java.lang包中的所有类。
* 如:String
* */
package com.a;
import com.day09.Demo1;
import static java.util.Arrays.sort;
import static java.lang.System.out;
import static com.a.Demo3.*;
public class Demo2 {
public static void main(String[] args) {
sort(new int[]{1,2,3});
out.println("hello");
show();
out.println(NUM);
new Demo3().method();
}
}
/*
* jdk1.5特性:
* 静态导入,导入的是静态成员(变量和方法),省略的是 包名.类名。
* 格式:
* import static 包名.类名.静态成员名;
* import static 包名.类名.*;
* 好处:简化了代码的书写
* 弊端:代码的阅读性降低
* */
package com.a;
public class Demo3 {
public static final int NUM= 100;
public static void show(){
System.out.println("show");
}
protected void method(){
System.out.println("method");
}
}
五. 权限修饰符
- 概述: 用来限定资源的使用范围的修饰词汇,就叫做权限(使用)修饰符,不同的符号有不同的限定范围
- 分类: 从小到大权限罗列
private :私有的 限定范围:本类中使用
默认的:啥也不写 限定范围:本类和本包中使用
protected:受保护的 限定范围:本类和本包中使用,不同包下的子类内部可以使用
public :公共的 限定范围:没有范围