java基础第六天——继承以及抽象类相关的知识

来源:互联网 发布:淘宝改评价步骤 编辑:程序博客网 时间:2024/06/17 11:06
继承: 在原有类的基础上,产生了一个新类,新类可以使用原有类中所有的非私有成员(成员变量,成员方法)


继承的好处:
提高了代表的可维护性
提高了代码的复用性
让类与类之间产生了继承关系

继承的弊端:
类与类之间的耦合度过高

设计代码的原则:
高内聚,低耦合

内聚: 自己能做的事情尽量自己完成,好处是,但其他人的代码更新的时候,对我的影响不大
耦合: 类与类之间的关联程度

继承特点:
java中类只能够单继承,不能多继承,可以多层继承
class Yy extends Object {}
class Fu extends Yy{}
class Zi extends Fu {}
所有的类都直接或者间接的继承了 Object类,Object类称为祖宗类

继承的注意事项:
1,使用关键字 extends 让类与类之间 产生继承关系
2, 父类私有的成员,子类不能继承,因为根本看不到
3, 构造方法不能继承 
4,不能为了继承某个功能而随意进行继承操作, 必须要符合 is a 的关系
苹果 is a 水果
男人 is a 人
狗   is a 人 , 这种情况就不能继承了

继承中的成员变量关系:
不同名的变量:
子类直接继承使用
同名的变量:
默认访问的是子类自己的成员变量, 想访问父类中的同名变量,请使用 super.成员变量;
—————————————————————————————
super: 指的是父类的存储空间(理解为父类的引用)
调用父类的成员变量:
super.成员变量;
调用父类的构造方法:
super(参数);
调用方法的成员方法:
super.成员方法();
—————————————————————————————
继承中的成员方法关系:
不同名的方法:
子类直接继承使用
同名的方法:
默认访问的是子类自己的成员方法,想访问父类中的同名方法,请使用 super.成员方法();

—————————————————————————————
方法重写:指 在子父类中,出现了方法声明相同的情况,也叫做方法覆盖,方法复写

方法重写的注意事项:
1,子类的方法声明要与父类相同
2, 子类要重写方法的方法,方法的权限修饰符不能比父类的更低
3, 父类私有的方法,子类不能够进行方法重写

方法重写(override):指 在子父类中,出现了方法声明相同的情况,也叫做方法覆盖,方法复写
方法重载(overload):指 在同一个类中,多个方法名称相同,它们的参数列表不同(个数不同,数据类型不同)

—————————————————————————————
类的完整初始化过程:
(静态成员变量,普通成员变量,静态代码块,普通代码块,构造方法, 子父类继承)
Zi z = new Zi();

1, 由于继承的关系,会将Fu.class 与 Zi.class 加载到内存中
1.1, 在栈空间中,开辟一个空间,存储 Zi类变量 z
1.2, 在堆空间中,开辟一个空间,存储new Zi()对象的成员信息
2, 由于继承关系super(),会先去调用父类中的空参数构造方法
3, 在父类中,完成父类中静态成员变量默认初始化操作
4, 在父类中,完成父类中静态代码块操作,进行父类静态成员初始化
5, 在子类中,完成子类中静态成员变量默认初始化操作
6,在子类中,完成子类中静态代码块操作,进行子类静态成员初始化
7,在父类中,完成父类中普通的成员变量默认初始化
8,在父类中,完成父类中普通的成员变量显示初始化
9, 在父类中,通过构造代码块,完成普通的成员变量初始化操作
10,在父类中,通过构造方法,完成普通的成员变量初始化操作
11,在子类中,完成子类中普通的成员变量默认初始化
12,在子类中,完成子类中普通的成员变量显示初始化
13,在子类中,通过构造代码块,完成普通的成员变量初始化操作
14,在子类中,通过构造方法,完成普通的成员变量初始化操作
15,将new Zi()对应的地址引用 赋值给 变量 z

—————————————————————————————
继承中的构造方法注意事项:
1,如果我们手动给出了构造方法,JVM不会在给我们提供默认的空参数构造方法
  如果我们没写任何的构造方法,JVM提供给我们一个空参数构造方法
  
2, 在构造方法中,默认的第一条语句为 super();
  它是用来访问父类中的空参数构造方法,进行父类成员的初始化操作

3, 当父类中没有空参数构造方法的时候,怎么办?
a: 通过 super(参数) 访问父类有参数的构造方法
b: 通过 this(参数) 访问本类中其他构造方法
  注意:[本类中的其他构造方法已经能够正常访问父类构造方法]


4, super(参数) 与 this(参数) 不能同时在构造方法中存在
—————————————————————————————
final:关键字,最终的意思
final修饰的类:最终的类,不能被继承
final修饰的变量: 相当于是一个常量, 在编译生产.class文件后,该变量变为常量值
final修饰的方法: 最终的方法,子类不能重写,可以继承过来使用

面试题:
1,局部变量使用final修饰
基本数据类型局部变量: 值不能改变
引用数据类型局部变量: 引用的地址值不能改变,元素内容可以改变,对象中的成员内容可以改变
2,final初始化时机
在构造方法结束之前,都可以为final修饰的成员进行初始化赋值
class Demo {
final int num;

public Demo(){
num = 10;//赋值成功
}
}
—————————————————————————————
多态:理解为同一种物质的多种形态


多态使用的前提:
1,有继承或者实现关系
2,要方法重写
3,父类引用指向子类对象

多态的成员访问特点:
方法的运行看右边,其他都看左边

多态的好处:
提高了程序的扩展性
多态的弊端:
不能访问子类的特有功能
—————————————————————————————
instanceof 关键字
格式: 对象名 instanceof 类名
返回值: true, false
作用: 判断指定的对象 是否为 给定类创建的对象
—————————————————————————————
抽象:不具体的,不明确的
抽象方法: 方法只有声明部分,没有方法体
抽象类: 包含抽象方法的类,一定是抽象类
         使用 abstract 修饰的类,是抽象类


抽象类的特点:  
1,抽象类与抽象方法都必须使用 abstract来修饰 
2,抽象类不能直接创建对象
  需要通过多态的方式,由子类创建对象,抽象类多态
3,抽象类中可以有抽象方法,也可以没有抽象方法
4,抽象类的子类
a,实现了抽象方法的具体类
b,抽象类


抽象类的成员特点:
成员变量:
普通变量
final变量
构造方法:

成员方法:
普通方法
抽象方法

抽象类面试题:
1,抽象类中是否可以没有抽象方法?如果可以,那么,该类还定义成抽象类有意义吗?为什么?
可以没有抽象方法,有意义,不会让其他人直接创建该类对象
2,抽象类不能直接创建对象,那么还有构造方法,有意义吗?为什么?
   有,子类创建对象,默认访问父类构造方法,为父类的成员初始化
3, abstract关键字与那些关键字冲突?
1,private 冲突
2,final   冲突
3,static  没意义
—————————————————————————————
接口:理解为是一个特殊的抽象类,但它不是类,是一个接口


接口的特点:
1,定义一个接口用interface关键字
interface Inter{}
2,一个类实现一个接口,实现implements关键字
class Demo implements Inter{}
3, 接口不能直接创建对象
  通过多态的方式,由子类来创建对象,接口多态

接口中的成员特点:
成员变量:
只能是final 修饰的常量
默认修饰符: public static final

构造方法:


成员方法:
只能是抽象方法
默认修饰符: public abstract 

类与类,类与接口,接口与接口之间的关系
类与类之间:继承关系,单继承,可以是多层继承
类与接口之间: 实现关系,单实现,也可以多实现
接口与接口之间:继承关系,单继承,也可以是多继承

Java中的类可以继承一个父类的同时,实现多个接口
—————————————————————————————
形式参数与返回值问题:
形式参数:
普通类: 要接收的是一个普通类的对象
抽象类: 要接收的是一个抽象类子类对象
接口:   要接收的是一个实现接口的子类对象

返回值:
普通类:返回的是普通类的对象
抽象类:返回的是抽象类子类对象
接口:  返回的是实现接口的子类对象

method("哈哈") 
public void method(String name){}
—————————————————————————————
包: package
理解: 文件夹的意思
包的划分:
按照模块:
cn.itcast.student
StudentAdd.java
StudentDelete.java
StudentUpdate.java
StudentFind.java

cn.itcast.teacher
TeacherAdd.java
TeacherDelete.java
TeacherUpdate.java
TeacherFind.java


功能分:
cn.itcast.add
StudentAdd.java
TeacherAdd.java
cn.itcast.delete
StudentDelete.java
TeacherDelete.java
cn.itcast.update
StudentUpdate.java
TeacherUpdate.java
cn.itcast.find
StudentFind.java
TeacherFind.java
—————————————————————————————
包的定义与带包的类的编译和运行

格式: package 包名.类名;


带包的类的编译和运行:
手动式:
1, javac java文件名.java, 产生字节码文件.class
2, 创建包所对应的文件夹, 把.class字节码文件放入最里层文件夹
3, java 包名.类名 方式运行,看结果

自动式:
1,javac -d 目录 java文件名.java
自动创建包所对应的文件夹, 把.class字节码文件放入最里层文件夹
2,java 包名.类名 方式运行,看结果
—————————————————————————————
包的注意事项:
1,在一个java文件中只能够定义一个包 package 
2,定义包的代码。必须是有效代码第一条
3, 在一个java文件中,可以使用多个 import 导包
4, 在一个java文件中,可以定义多个类class 

包的面试题:
package --> import --> class 

package 在最上面写
import  在中间
class   在最下面
—————————————————————————————
import: 导包, 用来导入包中所对应的类, 在调用类的时候,无需在编写包名
导包的格式:
import 包名.类名; 

import cn.lkp.Fu;
在创建对象的时候,不需要再编写包名
Fu f =new Fu();
—————————————————————————————
权限修饰符
public : 公共的
protected: 受保护的
默认的:在jdk1.8时候, 使用default 进行修饰
private : 私有的

public protected 默认的 private
在当前类中 YYY Y
同一包中的子类 Y Y Y
同一包中的其他类 Y Y Y
不同包中的子类 Y Y
不同包中的其他类 Y

—————————————————————————————
类及其组成可以用的修饰符


修饰符:
public : 公共的
protected : 受保护的
: 默认的
private :私有的
final : 最终的
static : 静态的
abstract : 抽象的

类:
public 默认的 final abstract
使用最多的是 public

成员变量:
public : 公共的
protected : 受保护的
: 默认的
private :私有的
final : 最终的
static : 静态的
使用最多的是 private 

构造方法:
public : 公共的
protected : 受保护的
: 默认的
private :私有的
使用最多的是 public

成员方法:
public : 公共的
protected : 受保护的
: 默认的
private :私有的
final : 最终的
static : 静态的
abstract : 抽象的
使用最多的是 public
—————————————————————————————
内部类: 在类中,定义了一个新类,这个新的类就是内部类
class A {//外部类
class B{// 内部类

}
}

特点: 
1,内部类可以直接访问外部类的成员,包含私有的成员
2, 外部类想要访问内部类的成员,必须创建内部类对象才可以访问

内部类的分类:
位置划分:
成员内部类:
class Outer{
//成员位置
class Inner(){//成员内部类

}
}

局部内部类:
class Outer{
public void method(){
//局部位置
class Inner(){//局部内部类

}
}
}

成员内部类常见的修饰符:
private : 提高内部类数据的安全性
static  : 方便了数据的访问调用


局部内部类的使用:
1,局部内部类可以使用外部类的成员,包含私有成员
2, 当局部内部类访问 外部类的局部变量的时候,局部变量需要 final修饰
必须被final修饰?
为什么呢?
因为局部变量会随着方法的调用完毕而消失,
这个时候,局部对象并没有立马从堆内存中消失,
还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,
这样,在堆内存里面存储的其实是一个常量值。通过反编译工具可以看一下

匿名内部类: 就是没有名字的内部类

使用的前提:
要有一个父类(普通类,抽象类)
或者有一个接口

格式:
new 父类 (){
//重写父类中所有的抽象方法
};

new 接口() {
//重写接口中所有的抽象方法
};

代码演示:
interface Inter {
public abstract void method();
}

//创建匿名内部类
new Inter(){
public void method(){
System.out.println("匿名内部类");
}
};

//匿名内部类调用方法的方式
new Inter(){
public void method(){
System.out.println("匿名内部类");
}
}.method();

—————————————————————————————
扩展:
interface Inter {
public abstract void method();
}
//使用下面的show方法
public void show( Inter in ){} // in --> 要的是接口子类对象
//使用的方式如下:
p.show(  new Inter(){
//重写接口中的抽象方法
public void method(){
System.out.println("我被调用了");
}
});

0 0
原创粉丝点击