继承:
继承可以理解为Java语言中面向对象的基石,因为他允许创建分等级层次的类:
使用继承的前提条件是:两个类存在共性,子类继承父类的特征或者行为.但是子类或者父类都可以有自己的一些独有特性
为什么要使用继承?
代码存在重复了,导致后果就是代码量大且臃肿,而且维护性不高,修改时容易出现错误,所以要从根本上解决这个问题,就需要继承,将共性内容提取出来,存放一个独立的类中.
继承的特性:
在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类
class A{
}
class B extends A{
}
Java语言中不支持多继承,虽然不支持多继承,但是支持多重继承
class A{
}
class B extends A{
}
class C extends B{
}
继承的缺点:耦合度高就会造成代码之间的联系越紧密,代码独立性越差
如果子类和父类的成员变量一致该怎么做呢?
遵循一个:"就近原则"
执行流程:
1)现在子类的局部位置中找,如果找到了就使用它
2)如果局部位置中没有,在子类的成员位置中找,如果找到了,就使用!
3)如果找不到,就在父类的成员位置中找,如果找到了,就使用
4)如果还找不到,就报错了,说明访问了一个不存在的变量!
代码块的概念:
在Java中用{}包起来的内容,将这个{}就称为代码块;
主要分为三类:
构造代码块
静态代码块:
-
随着类的加载而加载
-
优先于对象存在
-
他只执行一次
构造方法
优先级顺序是:静态代码块>构造代码块>构造方法
方法重写
在继承关系中,子类出现了和父类一模一样的方法,这时候子类会将父类的该功能覆盖掉
多态:
多态指同一种行为具有多种不同的表现形式
前提条件:
1)必须要有继承关系
2)方法重写:子类覆盖父类的功能
3)父类引用指向子类对象
向上转型:
父类名 对象名 = new 子类名() ;
特点:
编译和运行的过程
成员变量:编译看左边,运行看左边
成员方法:编译看左边运行看右边
静态成员方法:编译看左边运行看左边
构造方法:分层初始化,父类先初始化,然后子类在初始化,存在继承的关系
多态的好处:
1)提高了代码的复用性(由继承来保证)
2)提高了代码的扩展性(由多态来保证)
多态的弊端:
不能访问子类特有功能
解决方法:
1)创建子类的对象来访问子类的特有功能
2)向下转型,将父类的引用强制转换为子类的引用
子类名 对象名 = (子类名)父类的引用
final
指最终的不可更改的
被final修饰的成员方法不能被子类重写
特点:
1)修饰类:被修饰的类不能被继承
2)修饰成员变量:被修饰的成员变量就相当于是一个常量,因为不可更改
3)修饰成员方法:被修饰的方法不能被重写
4)final修饰的类和成员变量在内存中的地址不能被修改
抽象类:
在一个类中,如果该类仅仅存在方法声明,没有方法体,需要将这个类定义为抽象类
抽象类的书写格式:
abstract class A{
public abstract void 方法名();
}
定义
1)如果一个类是抽象类,那么该类中不一定存在抽象方法
如果一个方法是抽象方法,那么该类一定时抽象类
抽象类他是一个抽象概念,不能进行实例化,也就是在测试的时候不能够创建对象
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
需要存在具体的类
解决方法:
通过子类进行实例化,父类引用指向子类对象
抽象类多态:父类引用指向子类对象
子类必须将抽象类中的抽象方法全部重写,否则,该子类也必须声明为抽象类。
成员特点:
1)成员变量
即可以定义一个常量,也可以定义为变量
2)成员方法
即可以定义抽象方法,也可以定义非抽象方法
3)构造方法
存在构造方法,既可以有参构造也可以无参构造(作用:对数据进行初始化)
成员方法特点
成员方法如果是抽象方法,必须强制类完成的事情
成员方法如果是非抽象类方法,子类继承父类---来提高代码复用性.
封装:
指将成员变量私有化,对外提供公共的访问方法
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
封装的优点
良好的封装能够减少耦合。
类内部的结构可以自由修改。
可以对成员变量进行更精确的控制。
隐藏信息,实现细节。
主要是关键字private
class A{
private 私有成员变量
也可以定义私有成员方法
}
接口:
接口:体现的是事物的一种扩展性功能
接口表示方法:
public abstract void 方法名() ;
接口中需要注意:
1)接口只能定义抽象方法
2)接口不能实例化
3)接口通过自实现类进行实例化
格式:
接口名 对象名 = new 子实现类名();
接口的子实现类
1)子实现类不是具体类
2)接口中的子实现类必须是具体类,因为具体类可以创建对象
成员特点:
成员方法
必须是抽象方法,存在默认的修饰符public abstract
成员变量
接口名.成员变量变量被static修饰的只能是常量,存在默认修饰符public static final
构造方法:接口中不存在构造器,不存在构造方法
类鱼类之间:继承关系,只支持单继承,不可以多继承
类与接口之间的关系:实现关系,一个类继承另一个类的同时可以实现多个接口
格式
类名 implements 接口名{
重写接口方法
}
接口与接口
继承关系,既可以单继承也可以多继承
接口与抽象类的区别
1)成员变量:
抽象类:既可以定义常量,也可以定义变量
接口:只能是常量,存在默认修饰符public static final
成员方法:
抽象类:既可以使用抽象方法,也可以使用非抽象方法
接口:只能使用抽象方法,存在默认修饰符public abstract
构造方法:
抽象类:存在构造方法,多层初始化,父类先,后子类
接口没有构造方法
方法形式参数两种类型
基本数据类型
形参的改变对实参没有影响
引用类型
形参的改变对实参有直接的影响
具体类
实际调用该方法,实参需要传递该具体类的对象
抽象类
调用该方法,实参需要传递该具体类的对象
接口
调用该方法,实参需要传递该接口的子实现类对象
方法返回值问题
基本数据类型
需要什么数据类型,在调用方法的时候就使用该具体类型接收
引用数据类型
返回值结果是:
具体类:
需要返回该具体类的对象
抽象类
返回该抽象类的子类对象
接口
返回该接口的子实现类对象
内部类
就是在一个类中定义另外一个类
内部类的分类
成员内部类:在外部类的成员位置定义的类
在测试中要访问内部类的成员:
访问方式:外部类名.内部类名 对象名 = 外部类对象().内部类对象();
非静态的内部类中,不能存在静态变量
局部内部类
在局部位置定义的类
特点:
1)可以直接访问外部类的成员,包括私有
2)在外部类的成员方法中,可以通过创建局部内部类对象来访问局部内部类成员
加final的原因
局部变量的生命周期,随着方法的调用而存在,随着方法调用完毕而消失,而当前这个局部变量被局部内部类进行访问,在堆内存中对象不会立即回收,它还在使用这个局部变量,所有需要将这个变量定义为常量.
匿名内部类:它是内部类的一种简化方式,在局部位置使用
格式:new 类名/接口(){
重写方法
}
匿名内部类的好处:省去了繁杂的代码,不需要定义类里面的子类或者接口的子实现类
匿名内部类的本质:继承该类或者是实现了该接口的子实现类对象
特点:
1)在内部类中不存在继承关系
2)就近原则:在成员内部类中,如果外部类的成员变量和内部类成员变量名称一致,现在局部位置找,如果有就使用
3)在内部类中,可以通过外部类名.this,访问外部类里面的成员变量