1 多态
(1)同一个对象(事物),在不同时刻体现出来的不同状态
举例:
猫是猫,猫是动物。
水(液态,固态,气态)。
(2)多态的前提:
A:要有继承关系。
B:要有方法重写。
其实没有也是可以的,但是如果没有这个就没有意义。
动物 d = new 猫();
d.show();
动物 d = new 狗();
d.show();
C:要有父类引用指向子类对象那个。
A:成员变量
编译看左边,运行看左边
B:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
C:成员方法
编译看左边,运行看右边(成员方法存在重写)
D:静态方法
编译看左边,运行看左边
(静态和类相关,算不上重写,所以访问还是左边的)
由于成员方法存在方法重写,所以它看右边
class Fu{
public int num =100;
public void show(){
System.out.println("show Fu");
}
public static void function(){
System.out.println("function Fu");
}
}
class Zi extend Fu{
public int num =1000;
public int num2 =2000;
public void show(){
System.out.println("show Zi");
}
public static void function(){
System.out.println("function Zi");
}
}
class DuoTaiDemo{
public static void main(String[] args){
Fu f = new Zi();
System.out.println(f.num);
//报错 父类中找不到num2
//System.out.println(f.num2);
f.show();
f.function();
}
}
输出结果:100 show Zi function Fu
(4) 多态的好处
A:提高了代码的维护性(继承保证)
B:提高了代码的扩展性(调用时,直接调用父类名,而不用直接调用子类名)
例如:
Dog a = new Dog();
Cat b = new Cat();
Pig c = new Pig();
AnimalTool.useDog(a);
AnimalTool.useCat(b);
AnimalTool.usePig(c);
----------------------------------------
Dog a = new Dog();
Cat b = new Cat();
Pig c = new Pig();
AnimalTool.useAnimal(a);
AnimalTool.useAnimal(b);
AnimalTool.useAnimal(c);
(5) 多态的弊端
不能使用子类的特有功能,只能使用父类中定义了的功能。
那如何使用子类的特有功能?
A:创建子类对象调用特有功能。(可以,但是很多时候不合理,而且太占内存了)
Fu f = new Zi();
f.show();
//f.method(); 无法调用子类的method
//所以创建另一个子类对象
Zi z = new Zi();
z.show();
z.method();
B:把父类的引用强制转换为子类的引用。(向下转型)
Zi z = (Zi)f;
z.show();
z.method();
-----------------------------------------
对象间的转型问题:
向上转型:
Fu f = new Zi();
向下转型:
Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
(6) 继承的时候:
子类中有和父类一样的方法,叫做重写。
子类中没有父亲中出现过的方法,方法就被继承过来了
2 抽象类
(1)抽象类的概述:
动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。
我们把一个不是具体的功能成为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。
(2)抽象类的特点:
A:抽象类和抽象方法必须用abstract关键字修饰
B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
C:抽象类不能实例化
因为它不是具体的
抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
用于子类访问父类数据的初始化
D:抽象的子类
a:如果不想重写抽象方法,该子类是抽象类
b:重写所有的抽象方法,这个时候子类是一个具体的类
**抽象类的实例化其实是靠具体的子类实现的,是多态的方式。
Animal a = new Dog();
//抽象方法
//public abstract void eat(){} //空方法体,这个会报错,抽象方法不能有主体
public abstract void eat();
}
(3)抽象类的成员特点:
成员变量:既可以是变量,也可以是常量。
构造方法: 有。
用于子类访问父类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的。
抽象类的成员方法特性:
A:抽象方法,强制要求子类做的事情
B:非抽象方法 子类继承的事情,提高代码复用性。
(4)抽象类的几个小问题
A:一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义
a:可以
b:不让创建对象
B:abstract不能和哪些关键字共存
private 冲突 (不能被继承,但抽象要求重写)
final 冲突 (不能被重写,但抽象要求重写)
static 无意义 (抽象无方法体,static可以直接访问方法体)
3 接口
为了体现事物功能的扩展性,java中就提供了接口来定义这些额外功能,并不给出具体实现。
(1) 接口的特点:
A:接口用关键字interface表示
interface 接口名{}
B:类实现接口用implements表示
class 类名 implements 接口名{}
C:接口不能实例化
那么,接口如何实例化呢?
按照多态的方式来实例化
D:接口的子类
a:可以是抽象类,但意义不大
b:可以是具体类,要重写接口中的所有抽象方法(推荐方案)
由此可见:
A:具体类多态(几乎没有)
B:抽象类多态(常用)
C:接口多态(最常用)
//定义动物培训接口
interface AnimalTrain{
public abstract void jump();
}
(2)接口成员特点
成员变量:只能是常量
默认修饰符 public static final
构造方法:没有,因为接口主要是扩展功能的,而没有具体存在
成员方法:只能是抽象方法
默认修饰符public abstract
(3) 类与类:
继承关系:只能单继承,可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的时候同时实现多个接口。
接口与接口:
继承关系:可以单继承,也可以多继承
4 抽象类与接口的区别
A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以是常量
构造方法:无
成员方法:只可以是抽象
B:关系区别
类与类:
继承关系:只能单继承,可以多层继承。
类与接口:
实现关系,可以但实现,也可以多实现。
并且还可以在继承一个类的时候同时实现多个接口。
接口与接口:
继承关系:可以单继承,也可以多继承
**C:设计理念区别
抽象类 被继承体现的是:"is a"的关系,抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:"like a"的关系,接口中定义的是该继承体系的扩展功能。
5 形式参数和返回值问题
形式参数:
基本类型: 8种基本类型
引用类型:
类:(匿名对象的时候已经用过)需要的是该类的对象
抽象类:需要的是该抽象类的子类的对象
接口:跟抽象类同理
返回值类型:
基本类型: 8种基本类型
引用类型:
类:返回的是该类的对象
抽象类:返回的是该抽象类的子类的对象
接口:返回的是该接口的实现类的对象
6 链式编程
每次调用完毕方法后,返回的是一个对象。
class StudentDemo{
public Student getStudent(){
return new Student();
}
}
sd.getStudent().study();//链式编程
7 包
A:其实就是文件夹
B:作用
a:把相同的类名放到不同的包中
b:对类进行分类管理
举例:
学生:增加,删除,修改,查询
老师:增加,删除,修改,查询
。。。
方案1:按照功能分
cn.itcast.add
AddStudent
AddTeacher
cn.itcast.delete
DeleteStudent
DeleteTeacher
cn.itcast.update
UpdateStudent
UpdateTeacher
方案2:按照模块分
cn.itcast.teacher
AddTeacher
DeleteTeacher
UpdateTeacher
cn.itcast.student
AddStudent
DeleteStudent
UpdateStudent
包的定义
package 包名;
多级包用.分开即可
注意事项:
A:package语句必须是程序的第一条可执行的代码
B:package语句在一个java文件中只能有一个
C:如果没有package,默认表示无包名
8 不同包下类之间的访问
第一个问题:找不到Demo 需要用包名.Demo
第二个问题:程序包不存在 需要建立工程包
第三个问题:Demo在包中不是公共的,无法访问 设置访问权限。
导包:
格式:import 包名;
这种方式导入时到类的名称
**面试题:
package,import,class有没有顺序关系?
有
package>import>class
package:只能有一个
import:可以有多个
class:可以有多个,以后建议是一个
9 访问修饰符
public protected 默认 private
同一类中 √ √ √ √
同一包子类,其他类 √ √ √
不同包子类 √ √
不同包其他类 √
10 内部类
(1)内部类概述:把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。
(2)内部类的访问特点:
A:内部类可以直接访问外部类的成员,包括私有。
B:外部类要访问内部类的成员,必须创建对象。
(3)内部类位置:
成员位置:在成员位置定义的类,被称为成员内部类。
局部位置:在局部位置定义的类,被称为局部内部类。(例如方法中)
(4)成员内部类:
如何直接访问内部类的成员?
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer.Inner oi = new Outer().new Inner();
oi.show();
(5)成员内部类的修饰符:
**private:为了保证数据的安全性
**static:为了方便访问数据
注意:静态内部类访问的外部类数据必须用静态修饰
案例:我有一个人(人有身体,身体内有心脏)
不能直接让外部访问,必须要保证安全性。
class Body{
private class Heart{
public void operator(){
System.out.println("心脏搭桥");
}
}
public void method(){
if(如果你是外科医生){
Heart h = new Heart();
h.operator();
}
}
}
(6) 用static修饰后的内部类访问
class Outer{
private int num = 10;
private static int num2 = 100;
//内部类用静态修饰是因为内部类可以看出是外部类的成员
public static class Inner{
public void show(){
System.out.println(num);
}
public static void show2(){
System.out.println(num);
}
}
}
//格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
oi.show2();
//show2()的另一种调用方式
***11 成员内部类的面试题
要求请填空,分别输出30,20,10
class Outer{
public int num = 10;
class Inner{
public int num = 20;
public void show(){
int num = 30;
System.out.println(?); // num
System.out.println(??); // this.num
System.out.println(???); // Outer.this.num /new Outer().num
}
}
}
12 局部内部类
A:可以直接访问外部类的成员
B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
***面试题:
局部内部类访问局部变量的注意事项?
A:局部内部类访问局部变量必须使用final修饰
B:为什么?
局部变量是随着方法的调用而调用,随着调用完毕而消失。
而堆内存的内容并不会立即消失,所以,我们加finaal修饰。
加入final修饰后,这个变量就变成了常量,既然是常量,你消失了,我在内存中存储的数据是20,所以,我还是有数据在使用。
(反编译之后,就是一个常量)
class Outer{
private int num = 10;
public void method(){
final int num2 = 20;
class Inner{
public void show(){
System.out.println(num);
// 从内部类中访问本地变量num2,需要被声明为最终类型
System.out.println(num2);
}
}
Inner i = new Inner();
i.show();
}
}
(1)同一个对象(事物),在不同时刻体现出来的不同状态
举例:
猫是猫,猫是动物。
水(液态,固态,气态)。
(2)多态的前提:
A:要有继承关系。
B:要有方法重写。
其实没有也是可以的,但是如果没有这个就没有意义。
动物 d = new 猫();
d.show();
动物 d = new 狗();
d.show();
C:要有父类引用指向子类对象那个。
父 f = new 子类;
(3)多态中的成员访问特点:A:成员变量
编译看左边,运行看左边
B:构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
C:成员方法
编译看左边,运行看右边(成员方法存在重写)
D:静态方法
编译看左边,运行看左边
(静态和类相关,算不上重写,所以访问还是左边的)
由于成员方法存在方法重写,所以它看右边
class Fu{
public int num =100;
public void show(){
System.out.println("show Fu");
}
public static void function(){
System.out.println("function Fu");
}
}
class Zi extend Fu{
public int num =1000;
public int num2 =2000;
public void show(){
System.out.println("show Zi");
}
public static void function(){
System.out.println("function Zi");
}
}
class DuoTaiDemo{
public static void main(String[] args){
Fu f = new Zi();
System.out.println(f.num);
//报错 父类中找不到num2
//System.out.println(f.num2);
f.show();
f.function();
}
}
输出结果:100 show Zi function Fu
(4) 多态的好处
A:提高了代码的维护性(继承保证)
B:提高了代码的扩展性(调用时,直接调用父类名,而不用直接调用子类名)
例如:
Dog a = new Dog();
Cat b = new Cat();
Pig c = new Pig();
AnimalTool.useDog(a);
AnimalTool.useCat(b);
AnimalTool.usePig(c);
----------------------------------------
Dog a = new Dog();
Cat b = new Cat();
Pig c = new Pig();
AnimalTool.useAnimal(a);
AnimalTool.useAnimal(b);
AnimalTool.useAnimal(c);
(5) 多态的弊端
不能使用子类的特有功能,只能使用父类中定义了的功能。
那如何使用子类的特有功能?
A:创建子类对象调用特有功能。(可以,但是很多时候不合理,而且太占内存了)
Fu f = new Zi();
f.show();
//f.method(); 无法调用子类的method
//所以创建另一个子类对象
Zi z = new Zi();
z.show();
z.method();
B:把父类的引用强制转换为子类的引用。(向下转型)
Zi z = (Zi)f;
z.show();
z.method();
-----------------------------------------
对象间的转型问题:
向上转型:
Fu f = new Zi();
向下转型:
Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
(6) 继承的时候:
子类中有和父类一样的方法,叫做重写。
子类中没有父亲中出现过的方法,方法就被继承过来了
2 抽象类
(1)抽象类的概述:
动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。
我们把一个不是具体的功能成为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。
(2)抽象类的特点:
A:抽象类和抽象方法必须用abstract关键字修饰
B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
C:抽象类不能实例化
因为它不是具体的
抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
用于子类访问父类数据的初始化
D:抽象的子类
a:如果不想重写抽象方法,该子类是抽象类
b:重写所有的抽象方法,这个时候子类是一个具体的类
**抽象类的实例化其实是靠具体的子类实现的,是多态的方式。
Animal a = new Dog();
a.eat();
abstract class Animal{//抽象方法
//public abstract void eat(){} //空方法体,这个会报错,抽象方法不能有主体
public abstract void eat();
}
(3)抽象类的成员特点:
成员变量:既可以是变量,也可以是常量。
构造方法: 有。
用于子类访问父类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的。
抽象类的成员方法特性:
A:抽象方法,强制要求子类做的事情
B:非抽象方法 子类继承的事情,提高代码复用性。
(4)抽象类的几个小问题
A:一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义
a:可以
b:不让创建对象
B:abstract不能和哪些关键字共存
private 冲突 (不能被继承,但抽象要求重写)
final 冲突 (不能被重写,但抽象要求重写)
static 无意义 (抽象无方法体,static可以直接访问方法体)
3 接口
为了体现事物功能的扩展性,java中就提供了接口来定义这些额外功能,并不给出具体实现。
(1) 接口的特点:
A:接口用关键字interface表示
interface 接口名{}
B:类实现接口用implements表示
class 类名 implements 接口名{}
C:接口不能实例化
那么,接口如何实例化呢?
按照多态的方式来实例化
D:接口的子类
a:可以是抽象类,但意义不大
b:可以是具体类,要重写接口中的所有抽象方法(推荐方案)
由此可见:
A:具体类多态(几乎没有)
B:抽象类多态(常用)
C:接口多态(最常用)
//定义动物培训接口
interface AnimalTrain{
public abstract void jump();
}
(2)接口成员特点
成员变量:只能是常量
默认修饰符 public static final
构造方法:没有,因为接口主要是扩展功能的,而没有具体存在
成员方法:只能是抽象方法
默认修饰符public abstract
(3) 类与类:
继承关系:只能单继承,可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的时候同时实现多个接口。
接口与接口:
继承关系:可以单继承,也可以多继承
4 抽象类与接口的区别
A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以是常量
构造方法:无
成员方法:只可以是抽象
B:关系区别
类与类:
继承关系:只能单继承,可以多层继承。
类与接口:
实现关系,可以但实现,也可以多实现。
并且还可以在继承一个类的时候同时实现多个接口。
接口与接口:
继承关系:可以单继承,也可以多继承
**C:设计理念区别
抽象类 被继承体现的是:"is a"的关系,抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:"like a"的关系,接口中定义的是该继承体系的扩展功能。
5 形式参数和返回值问题
形式参数:
基本类型: 8种基本类型
引用类型:
类:(匿名对象的时候已经用过)需要的是该类的对象
抽象类:需要的是该抽象类的子类的对象
接口:跟抽象类同理
返回值类型:
基本类型: 8种基本类型
引用类型:
类:返回的是该类的对象
抽象类:返回的是该抽象类的子类的对象
接口:返回的是该接口的实现类的对象
6 链式编程
每次调用完毕方法后,返回的是一个对象。
class StudentDemo{
public Student getStudent(){
return new Student();
}
}
sd.getStudent().study();//链式编程
7 包
A:其实就是文件夹
B:作用
a:把相同的类名放到不同的包中
b:对类进行分类管理
举例:
学生:增加,删除,修改,查询
老师:增加,删除,修改,查询
。。。
方案1:按照功能分
cn.itcast.add
AddStudent
AddTeacher
cn.itcast.delete
DeleteStudent
DeleteTeacher
cn.itcast.update
UpdateStudent
UpdateTeacher
方案2:按照模块分
cn.itcast.teacher
AddTeacher
DeleteTeacher
UpdateTeacher
cn.itcast.student
AddStudent
DeleteStudent
UpdateStudent
包的定义
package 包名;
多级包用.分开即可
注意事项:
A:package语句必须是程序的第一条可执行的代码
B:package语句在一个java文件中只能有一个
C:如果没有package,默认表示无包名
8 不同包下类之间的访问
第一个问题:找不到Demo 需要用包名.Demo
第二个问题:程序包不存在 需要建立工程包
第三个问题:Demo在包中不是公共的,无法访问 设置访问权限。
导包:
格式:import 包名;
这种方式导入时到类的名称
**面试题:
package,import,class有没有顺序关系?
有
package>import>class
package:只能有一个
import:可以有多个
class:可以有多个,以后建议是一个
9 访问修饰符
public protected 默认 private
同一类中 √ √ √ √
同一包子类,其他类 √ √ √
不同包子类 √ √
不同包其他类 √
10 内部类
(1)内部类概述:把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。
(2)内部类的访问特点:
A:内部类可以直接访问外部类的成员,包括私有。
B:外部类要访问内部类的成员,必须创建对象。
(3)内部类位置:
成员位置:在成员位置定义的类,被称为成员内部类。
局部位置:在局部位置定义的类,被称为局部内部类。(例如方法中)
(4)成员内部类:
如何直接访问内部类的成员?
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer.Inner oi = new Outer().new Inner();
oi.show();
(5)成员内部类的修饰符:
**private:为了保证数据的安全性
**static:为了方便访问数据
注意:静态内部类访问的外部类数据必须用静态修饰
案例:我有一个人(人有身体,身体内有心脏)
不能直接让外部访问,必须要保证安全性。
class Body{
private class Heart{
public void operator(){
System.out.println("心脏搭桥");
}
}
public void method(){
if(如果你是外科医生){
Heart h = new Heart();
h.operator();
}
}
}
(6) 用static修饰后的内部类访问
class Outer{
private int num = 10;
private static int num2 = 100;
//内部类用静态修饰是因为内部类可以看出是外部类的成员
public static class Inner{
public void show(){
System.out.println(num);
}
public static void show2(){
System.out.println(num);
}
}
}
//格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
oi.show2();
//show2()的另一种调用方式
Outer.Inner.show2();
静态内部类的作用:
https://www.zhihu.com/question/28197253***11 成员内部类的面试题
要求请填空,分别输出30,20,10
class Outer{
public int num = 10;
class Inner{
public int num = 20;
public void show(){
int num = 30;
System.out.println(?); // num
System.out.println(??); // this.num
System.out.println(???); // Outer.this.num /new Outer().num
}
}
}
12 局部内部类
A:可以直接访问外部类的成员
B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
***面试题:
局部内部类访问局部变量的注意事项?
A:局部内部类访问局部变量必须使用final修饰
B:为什么?
局部变量是随着方法的调用而调用,随着调用完毕而消失。
而堆内存的内容并不会立即消失,所以,我们加finaal修饰。
加入final修饰后,这个变量就变成了常量,既然是常量,你消失了,我在内存中存储的数据是20,所以,我还是有数据在使用。
(反编译之后,就是一个常量)
class Outer{
private int num = 10;
public void method(){
final int num2 = 20;
class Inner{
public void show(){
System.out.println(num);
// 从内部类中访问本地变量num2,需要被声明为最终类型
System.out.println(num2);
}
}
Inner i = new Inner();
i.show();
}
}