1.继承
1.1继承的语法格式
定义格式
class B{}
class A extends B{} // A 继承 B类
1.2 继承的好处
上面案例,使用程序中的继承,使用继承的好处:
-
减少代码量
-
复用性提高
-
继承的存在,导致了面向对象的最后一个特征多态
继承有弊端: 类和类之间的紧密性更强.(扩展性越差)
2. 继承后成员特点
2.1 继承后成员变量特点
子类和父类中的成员变量同名
-
调用的使用: 子类自己有,使用自己的,子类没有,使用父类
2.2 super关键字
super关键字是超级的意思,在子类中调用父类的成员,使用此关键字
super.变量 调用父的成员变量
super.方法() 调用的是父类的成员方法
2.3 方法重写的意义
继承本质是扩展的意思,延伸的意思,依靠方法的重写来实现
2.4 继承后构造方法特点
构造方法特点: 子类的构造方法中,第一行存在隐式代码 (写不写都存在),代码是super(); 调用父类的无参数构造方法.
3.继承特点
3.1 单继承
class A extends B,C{} //不允许的行为
3.2多层继承
class A extends B{}
class B extends C{}
//多层继承,允许实现
//class C extends Object{}
4. 对象的多态性
4.1 对象多态性前提
- 必须有继承或者是接口实现
- 必须有方法的重写
多态的语法规则: 父类或者接口的引用指向自己的子类的对象
父类 变量(对象名) = new 子类对象(); //多态写法
4.2多态中成员的特点
-
多态中成员变量的特点
- 编译 : 父类中没有成员变量,编译失败
- 运行 : 运行父类中的成员变量
-
多态中成员方法的特点
- 编译 : 父类中没有成员方法,编译失败
- 运行 : 运行子类的方法重写
-
简练 : 成员方法编译看左边,运行看右边.成员变量都是左边
4.3多态的转型
转后类型 变量名 = (转后类型)要转的数据; //公式
public static void main(String[] args) {
//创建对象,多态性
//父类 = new 任意子类对象() 扩展
Animal animal = new Cat();
animal.eat();
//Cat类的特有功能 catchMouse()方法
//类型转换,强制
//Cat提升为了Animal,转回Cat类型
Cat c = (Cat)animal;
c.catchMouse();
}
5.抽象类abstract
抽象的概念 : 凡是说不清楚的都是抽象
例子 : 我买了一台手机,买了一直笔,都是抽象概念.
具体: 华为Meta40Pro ,金属, 16G+512
程序中 : 我知道这个功能存在,但是怎么完成就说不清楚,程序中也出现了抽象.
5.1 抽象方法定义
使用关键字 abstract定义抽象方法
权限修饰符 abstract 返回值类型 方法名字(参数列表) ;
abstract关键字
抽象方法没有方法体, 不需要{},直接分号结束
public abstract class 类名{}
5.2抽象类的使用方式
- 抽象类不能实例化对象,不能new对象.
- 为什么不能建立对象,类中有没有主体的方法存在,建立对象调用抽象方法是绝对的错误,因此不能建立对象.
- 需要子类继承抽象类,重写抽象方法.
- 创建子类对象
- 使用多态性创建对象,调用方法执行子类的重写
5.3抽象类中的成员的定义
5.3.1抽象类中能否定义成员变量
可以定义成员变量,成员变量私有修饰,提供方法 get/set,由子类的对象使用
public abstract class Animal {
//抽象类中能否定义成员变量
private String name;
public abstract void eat();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
5.3.2 抽象类中的构造方法
抽象类中有构造方法,不写有默认的
5.4当子类还是抽象类
当一个子类继承一个抽象类的时候,子类必须重写全部的抽象方法.假如子类重写了部分抽象方法,这个子类依然还是抽象类.
6.接口interface
6.1Java中接口定义
public interface 接口名{}
6.2接口中定义成员
接口中成员定义 (JDK1.7 版本)
-
成员变量
-
成员变量的定义是具有固定格式
-
成员变量的修饰符是固定 public static final
public static final 数据类型 变量名 = 值 ;
-
成员方法
-
成员方法的定义是具有固定格式
-
成员方法的修饰符固定为 public abstract
public abstract 返回值类型 方法名(参数列表) ;
6.3接口的使用方式
- 接口不能建立对象,不能new
- 需要定义类,实现接口(继承类,在接口中称为实现,理解为继承)
- 实现接口,使用新的关键字 implements
- 实现的格式
class 类 implements 接口名{}
- 重写接口中的抽象方法
- 创建子类的对象
6.4接口的多实现
语法格式:
class 类名 implements 接口A,接口B{}
实现方法:
/**
* 实现接口A和B
*/
public class C implements A,B{
@Override
public void a() {
System.out.println("重写A接口方法");
}
@Override
public void b() {
System.out.println("重写B接口方法");
}
}
6.5.接口之间的关系
类和类之间是继承关系(单继承),类和接口之间是实现关系(多实现implements),接口和接口之间是继承关系,支持多继承,一个接口可以同时继承多个接口.
interface A extends B,C,D{}
6.6 实现类还是抽象类
实现类实现接口,重写一部分抽象方法,实现类还是一个抽象类
7.静态修饰符
static修饰符 : 最早出现在main方法中.只能修饰成员,不能写在方法的内部,被static修饰的成员,静态成员变量和静态的成员方法.
7.1静态修饰成员变量
static 修饰的成员变量,是被所有的对象共享的数据.没有被static修饰的成员变量,是每个对象的独享数据或者是特有数据.
7.2静态内存
- 静态成员内存的特点
- 静态成员跟随自己的类进入到元数据区(静态区域)
- 静态成员属于自己的类,不属于对象
- 静态成员进入内存后,赋默认值
- 静态成员变量的初始化实际早于对象
7.3静态成员的调用
静态的内存图中,已经很明白了,静态属于自己的类,不是对象,静态的调用方式应该是
类名.静态成员
7.4静态方法
静态方法直接类名调用. 静态方法中不能直接使用非静态成员.
静态是先人,非静态是后人. 静态出现在内存的时间早于非静态
7.5main方法
- main方法详解
- public 最大权限 : main方法的调用者是JVM
- static 无需对象,被类名直接调用,JVM启动的时候使用类名.main启动程序
- void 无返回值,调用者是JVM,方法的返回值都是返回给调用者,JVM不需要返回值,没有意义
- main 固定方法名称
- args 字符串的数组,JVM调用方法main必须传递参数,后期对JVM设置参数
8.final修饰
final修饰符是最终的意思,不可改变.final可以修饰类,修饰方法,修饰成员变量,修饰局部变量.
8.1final修饰类
被final修饰的类,称为最终类,不能被其他的类继承,无子类.
8.2 final修饰方法
被final修饰的方法,最终方法,不能被子类重写,和调用无关.
8.3 final修饰局部变量
变量定义在方法的内部,是局部变量, 被final修饰后,一次赋值,终身不改变,锁死了变量的值,看做是常量.
- final修饰的基本类型,锁死值
- final修饰的引用类型,锁死内存地址 (引用类型中的成员不受影响)
- final修饰了方法的参数,调用者传递值后,方法的参数值就锁死
8.4 final修饰成员变量
成员变量的定义位置,是在类中,方法外面.成员变量在内存中有默认值.final修饰成员变量的时候,锁住的不是内存默认值,而是我们程序人员手动的赋值.
- 成员变量赋值,可以定义直接写值
int age = 0;
- 成员变量赋值,可以使用构造方法
public Student(int age){this.age=age;}
- 成员变量赋值,可以使用set方法完成
- final修饰的成员变量,可以构造方法赋值,不能set方法赋值
- 构造方法在new对象的时候,执行一次,仅仅一次
- 可set方法,反复执行!!
9.代码块
9.1 静态代码块
写在类中方法外面 : static{}
静态代码块的执行时机 : 只要使用了这个类的成员(new对象,调用静态方法,静态变量),静态代码块就会执行,而且就一次
9.2 构造代码块
写在类中方法外面的 {}, 创建对象的时候运行,new一次,运行一次
9.3 局部代码块
写在方法内部的 {} 局部代码块,没有用
9.4初始化过程
- 父类.class文件先进入内存
- 子类.class文件再进入内存
- 初始化父类的静态成员(变量,代码块,方法)
- 初始化子类的静态成员
- 运行父类的静态代码块
- 运行子类的静态代码块
- 运行父类的构造代码块
- 运行父类的构造方法
- 运行子类的构造代码块
- 运行子类的构造方法
10.内部类
概述 : 所谓内部类,就是在一个类的内部,定义了另外的一个类
class A{ //外部类,封闭类
class B{} //内部类,嵌套类
}
10.1 成员内部类
成员内部类,是一个类定义在了另一个类的成员位置.这个内部类可以使用成员修饰符,public static final private .
对于内部来说 : 可以直接使用外部类的成员,如果外部类要使用内部类的成员,必须要创建对象.
public static void main(String[] args) {
//调用内部类的方法inner()
Outer.Inner oi = new Outer().new Inner();
oi.inner();
}
10.2 局部内部类
局部内部类 : 要定义在方法里面. 方法里面是局部位置,不能使用成员修饰符,权限,静态不能用
class A{
public void a(){
class B{} //局部内部类
}
}
局部内部类,访问局部变量,变量必须final修饰
10.3 匿名内部类
匿名内部类,就是没有名字的内部类,只能写在方法中,为了简化代码书写.
简化 : 实现类,实现接口,重写方法,创建对象. 或者是子类继承父类,重写方法,创建对象.代码上少内容.
匿名内部类使用的前提 :
-
必须有接口实现,或者是类的继承
-
格式 :
new 接口或者父类(){ //重写抽象方法 }; 格式 == 实现类,实现接口,重写方法,创建对象
public interface MyInter { public abstract void inter(); public abstract void inter2(); }
public class InnerClassTest { public static void main(String[] args) { //匿名内部类,简化书写,不写实现类 //同时调用多个重写方法 /* * new MyInter(){}; 是接口实现类的匿名对象 * 多态 : 接口 变量 = 实现类对象 */ MyInter my = new MyInter(){ @Override public void inter() { System.out.println("实现类实现接口重写方法"); } @Override public void inter2() { System.out.println("实现类实现接口重写方法2222"); } }; my.inter(); my.inter2(); } }
11. 非法修饰符组合
非法的修饰符的组合,主要说的是抽象abstract
- abstract和private就是非法组合,抽象方法要重写,private不能继承
- abstract和final就是非法组合,抽象方法要重写,final修饰不能重写
- abstract和static就是非法组合,静态方法类名直接调用