final修饰局部变量:
基本数据类型:如果局部变量是基本数据类型,被final修饰,基本类型的变量值不可能在改变.
引用数据类型:如果final修饰引用类型的变量,那么它不能在重新分配堆内存空间,但是可以改变成员变量的值
多态:一个事物在不同时刻体现的不同状态;
eg:水:固态,气态,液态
多态的好处(特点):
1. 提高代码的维护性(由继承保证)
2. 提高代码的扩展性(由多态保证)
开发的原则:低耦合,高内聚
多态的三个前提条件:
1. 必须要有继承关系(如果没有继承关系,谈不上多态)
2. 必须要有方法重写
子类出现了和父类一样的 方法声明
3. 有父类引用指向子类对象:向上转型
Fu f=new Zi();
多态的成员访问特点:
1.成员变量:编译看左,运行看左
2.成员方法(非静态的成员方法):
编译看左,运行看右:由于存在方法重写,所有就运行最终的就是子类的成员方法
3.静态成员方法(静态方法算不上方法重写,静态直接和类有关!)
4.构造方法:还是对象进行初始化,由于是一种继承关系,还是分层初始化!
Eg:
class Fu{
public int num = 10 ;
public void show(){
System.out.println("showFu...");
}
public static void function(){
System.out.println("functionFu....");
}
}
class Zi extends Fu{
int num = 20 ;
public void show(){
System.out.println("showZi...");
}
public static void function(){
System.out.println("functionZi....");
}
}
public class DuoTaiText1 {
public static void main(String[] args) {
Fu f = new Zi() ;
System.out.println(f.num);
f.show() ;
f.function() ;
}
}
输出结果
10
show Zi...
function Fu....
多态的弊端:不能访问子类的特有功能:
解决方法:
1. 创建子类对象.通过子类对象来访问子类的特有功能:但是必须要在堆内存新开辟空间(不支持)
异常:OOM异常:严重问题:OutOfMemory(内存溢出):垃圾回收器回收的没有创建的块会出现
2.多态的第三个前提条件:父类引用子类对象 为向上转型:因此子类可以引用父类对象
向下转型:将父类的引用强制转换为子类的引用:前提必须有父类的引用存在
向下转型必须依附于向上转型!
注意:一般只能向下转型一次:
class Animal3{
public void show(){
System.out.println("showAnimal2...");
}
}
class Cat3 extends Animal3{
public void show(){
System.out.println("showCat2....");
}
//特有功能
public void playGame(){
System.out.println("猫玩毛线...");
}
}
public class DuoTaiText2 {
public static void main(String[] args) {
Animal3 a = new Cat3() ; //向上转型
a.show() ;
Cat3 c = (Cat3) a ;// 向下转型
c.playGame() ;
}
}
向下转型使用不当是会造成一个异常:
当向下转型已经一次后,再进行向下转型(编译会通过,执行会报错)
因此一般向下转型只执行一次.
案例:孔子装爹:
//孔子爹
class ConfuciusFather {
public int age=40;
public void teach(){
System.out.println("讲解语文");
}
}
//孔子继承他爸
class Confucius extends ConfuciusFather{
public int age=18;
public void teach(){
System.out.println("讲解论语");
}
public void playGame(){
System.out.println("打游戏");
}
}
//测试类
public class DuoTaiText {
public static void main(String[]args){
ConfuciusFather k=new Confucius();
System.out.println(k.age);
k.teach();
// 向下转型
Confucius k1=(Confucius) k;
k1.playGame();
}
}
多态中:
有继承关系:分层初始化:父类初始化,然后子类初始化.
多态的访问特点:成员方法(非静态的):编译左,运行右.
抽象类的概念:
每一个动物的吃和睡的功能不一样,不应该把动物类定义为一个具体类,而是给出一个声明(abstract).
当一个类中如果有抽象功能(抽象方法)的时候,那么这个类一定要定义为抽象类!
一个类中可以有抽象方法.也可以有非抽象方法 .
抽象类不能实例化::抽象类不能创建对象
一个抽象类如果进行实例化: 通过抽象类多态形式:父类的引用指向子类对象,通过子类进行初始化!
抽象类的子类的特点: 如果抽象类的子类是抽象类,那么没有意义.因为通过子类进行对象初始化的.
抽象类多态: 强制子类必须重写当前抽象的父类中所有的抽象方法
Eg:abstract class Animal{
//抽象方法
public abstract void eat() ;
public abstract void sleep() ;
public void show(){
System.out.println("showAnimal....");
}
}
//子类是具体类
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫趴着睡觉..");
}
}
//测试类
public class DuoTaiText3 {
public static void main(String[] args) {
// Animal a = new Animal();
//父类抽象类因此无法创界对象
//多态:父类引用指向子类对象
Animal a = new Cat() ; //Animal是抽象类,---->抽象类多态形式
a.eat() ;
a.sleep() ;
a.show();
}
}
输出结果:
猫吃鱼
猫趴着睡觉..
show Animal....
抽象类的成员特点
成员变量:可以是变量也可以是自定义常量
构造方法: 抽象类可以有构造方法:包括有参构造和无参构造
* 作用:通过抽象类多态的形式:让子类进行数据的初始化
成员方法:可以是抽象方法也可以是非抽象方法.
抽样类的方法特性:
抽象方法:强制子类必须做到一件事情:方法重写(覆盖).
非抽象方法:由继承保证提高复用性.
Eg:
abstract class Fu{
privateString name ;
privateint age ;
publicint num = 100 ;
publicFu(){
}
publicFu(String name,int age){
this.name= name ;
this.age= age ;
}
//抽象方法
publicabstract void show();
publicvoid function(){
System.out.println("functionFu...");
}
}
//子类
class Zi extends Fu{
@Override
publicvoid show(){
System.out.println("showZi....");
}
}
//测试类
public class AbstractDemo2 {
publicstatic void main(String[] args) {
Fuf = new Zi() ;
f.show();
f.function();
}
}
一个类中如果没有抽样方法,这个类可以定义为一个抽样类吗?
可以 但是不能让其创建对象
Abstract不能和那些关键字连用?
Private和abstract /final和abstract/static和abstract
实际开发中:public公共访问权限
接口的概念:
接口体现的是一种扩展功能: eg:猫可以跳高(部分猫可以跳高)
如何表示接口: interface:接口 interface 接口名{
}
接口里面的方法可以是非抽象类方法吗:只能是抽象方法
接口中不能有构造方法
接口的特点:不能实例化(不能直接创建对象):
通过子实现类来实例化:1.接口的子实现类是抽象类,没有意义,子类不能创建对象
2. 接口的子实现类是非抽象类.通过子类实现类对数据进行初始化
接口的自实现类和接口的关系 implements:
Class 子实现类名 implement(实现)接口名{
}
Eg:
//接口
public interface Jump {
public abstract void jump();
}
//接口的子实现类
class Dog implements Jump{
@Override
public void jump() {
System.out.println("狗可以跳高了");
}
}
//测试类
public class Interface {
public static void main(String[] args) {
//接口多态:接口的引用指向子实现类对象
Jump j = new Dog() ;
j.jump();
}
}
接口成员的特点:
成员变量:只能是常量:存下默认修饰符:public static final(自己给出默认修饰符)
构造方法:接口没有构造方法
成员方法:接口中的成员方法默认修饰符:public abstract(默认修饰)
定义接口的子实现类:见名知意:接口名+impl
类与类的关系:继承关系:extends ,Java只支持单继承,不支持多继承,但是可以多层继承!
类与接口的关系:实现关系:implements,并且,一个类继承另一个类的同时,可以实现多个接口
(class 子实现类名 extends Object implements 接口1,接口2..)
接口与接口的关系: 继承关系:extends,可以支持单继承,也可以多继承!
面试题:接口和抽象类的区别
1. 成员的区别:
成员变量:抽象类:成员变量可以是常量,也可以是变量
接口:成员变量只能是一常量:存在默认修饰符:public static final
构造方法:
抽象类:可以有无参构造,有参构造方法
作用:通过子类进行数据初始化(通过子类创建对象)
接口:没有构造方法
成员方法的区别:
抽象类:可以有抽象方法,也可以有非抽象方法.
接口:只能是抽象方法:存在默认修饰符:public abstract
2. 关系的区别
3. 设计理念的区别
抽象类:体现是is a 的关系,存在继承关系!(抽象类多态)
接 口:体现的是一种like a的关系,体现接口的一种扩展功能.