java 继承和多态 抽象类和接口
2012-08-30 09:46
381 查看
继承:Encapsulation
1.提高了代码的复用性
2.让类与类产生了关系,才有了多态的特性
注意:不要为了获取其他类的功能,简化代码而继承
必须是类与类之间有所属关系才可以继承,所属关系 is a
继承出现后,子父类成员的特点:
类中成员:
1.变量
2.函数
3.构造函数
1.变量
如果子类中出现了非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super
2.函数
当子类出现和父类一模一样的函数时
当子类对象调用该函数,会运行子类函数的内容
如同父类的函数被覆盖一样
这种情况是函数的另一个特性:重写(覆盖,复写)
当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖,保留父类的功能定义,并重写功能内容
覆盖:
1.子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败
2.静态只能覆盖静态
3.构造函数
在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句 super()
super():会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super()
为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的.所以子类在对象初始化时,要先访问一下父类中的构造函数
如果要访问父类中指定的构造函数,可以通过手动定义super语句方式来指定
注意:super 语句一定定义在子类构造函数的第一行
子类的实例化过程:
结论:子类的所有构造函数,默认都会访问父类中空参数的构造函数,因为每一个子类构造函数内第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super形式来指定要访问父类中的构造函数
当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数
final:最终.
作为一个修饰符,
1.可以修饰类,函数,变量.
2.被final修饰的类不可以被继承,为了避免被继承,被子类复写功能
3.被final修饰的方法不可以被覆盖
4.被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读星,都给这些值起个名字,方便于阅读,而这个值不需要改变,所以加上final修饰.作为常量,常量的书写规范,所有字母都大写,如果由多个单词组成,单词间通过_连接
public static final 全局常量
5.内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量
当多个类中出现相同功能,但是功能主题不同,这时可以向上抽取,只抽取功能定义,而不抽取功能主体
抽象类的特点:
1.抽象方法一定在抽象类中
2.抽象方法和抽象类都必须被abstract关键字修饰
3.抽象类不可以用new创建对象,因为调用抽象方法没意义
4.抽象类中的方法要被使用,必须由子类复写所有的抽象方法后,建立子类对象调用,如果子类值覆盖了部分抽象方法,那么该子类还是一个抽象类
抽象类和一般类没有太大的不同.
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不得的东西,这些不确定的部分,也是该事物的功能,需要明确实现,但是无法定义主体,通过抽象方法来表示
抽象类比一般类多了抽象方法,就是可以定义抽象方法
抽象类不可以实例化
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让改类建立对象
/*
需求:获取一段程序运行的时间.
原理:获取程序开始的时间,并获取程序结束的时间,相减
获取时间:System.currentTimeMillis();
*/
abstract class GetTime
{
public final void getTime(){
long start = System.currentTimeMillis();
fun();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
abstract void fun();
}
class SubTime extends GetTime
{
public void fun(){
for(int i = 0;i<4000;i++){
System.out.print(i);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
GetTime gt = new SubTime();
gt.getTime();
}
}
/*
这种方式,就是模版方法设计模式,-->提高扩展性,复用性
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时候,就将不确定的部分暴露出去,由该类的子类去完成
*/
接口:初期,可以理解认为是一个特殊的抽象类
class用于定义类
interface 用于定义接口
接口定义时,格式的特点:
1.接口中常见定义: 常量,抽象方法
2.接口中的成员都有固定修饰符
常量:public static final -->可以省略
方法:public abstract -->可以省略
建议:为了增加阅读性,不建议省略
可以看出:接口中的成员都是public的
接口是不可以创建对象的,因为有抽象方法,需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类是一个抽象类
类实现接口关键字:implements
接口可以被类多实现.
类与类之间有继承关系,类与接口之间有实现关系,接口与接口之间是继承关系
所以java在接口与接口之间存在多继承关系
接口的特点:
接口是对外暴露的规则.
接口是程序的功能扩展
接口的出现降低了系统间的耦合度
---------------------------------
多态:可以理解为事物存在多种体现形态
人:男人,女人
动物:猫,狗
猫 cat = new 猫();
动物 animal = new 猫();
一个类中可以有多个方法以重载的方式存在也是多态的体现
java中主要说的是对象的多态性
1.多态的体现
父类引用指向子类对象
(父类引用可以接收子类对象)
2.多态的前提
必须类与类有关系,要么继承,要么实现
一般还有一个前提:存在覆盖
3.多态的好处
多态的出现提供了程序的扩展性
4.多态的弊端:
但只能使用父类的引用访问父类中的成员
5.多态的应用
6.多态的出现代码中的特点(多态使用的注意事项)
Animal a = new Cat();//类型提升,向下转型
如果想调用子类特有方法时,可以强制将父类的引用,转成子类类型,也叫向下转型
千万不要讲父类对象转成子类类型
我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换.多态自始至终都是子类对象做变化
在多态中成药函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,没有,则编译失败.
在运行时期:参阅对象所属的类中是否有调用的方法
简单总结就是:成员函数在多条调用时,编译看左边,运行看右边
在多态中,成员变量的特点
无论编译和运行,都参考左边(引用型变量所属的类)
在多态中,静态成员函数的特点:
无论编译和运行,都参考左边
给你个例子
class Fu {
int num = 5;
void method1() {
System.out.println("fu method_1");
}
void method2() {
System.out.println("fu method_2");
}
static void method3() {
System.out.println("fu method_3");
}
}
class Zi extends Fu {
int num = 8;
void method1() {
System.out.println("zi method_1");
}
static void method3() {
System.out.println("zi method_3");
}
}
public class C{
public static void main(String args[]) {
Fu f = new Zi();
System.out.println(f.num);//5
多态中成员变量的特点,
无论编译和运行,都参考左边(引用变量所属的类)
f.method1(); //zi method_1//覆盖
f.method2(); //fu method_2
多态中非静态函数的特点,
在编译时期:参阅引用类型变量所属的类中是否调用的方法,如有,编译通过,如没有,编译失败
在运行时期:参阅对象所属的类中是否有调用的方法
简单的总结就是:成员函数在多态调用时,编译看左边,运行看右边
f.method3(); //fu method_3
在多态中,静态成员函数的特点,
无论编译和运行,都参考左边
当静态方法一进内存,就已经绑定在所属的类上了(静态绑定)
}
}
Object:是所有对象的直接或者间接父类
该类中定义的肯定是所有对象都具备的功能
equals()
hashCode()
toString()
1.提高了代码的复用性
2.让类与类产生了关系,才有了多态的特性
注意:不要为了获取其他类的功能,简化代码而继承
必须是类与类之间有所属关系才可以继承,所属关系 is a
继承出现后,子父类成员的特点:
类中成员:
1.变量
2.函数
3.构造函数
1.变量
如果子类中出现了非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super
2.函数
当子类出现和父类一模一样的函数时
当子类对象调用该函数,会运行子类函数的内容
如同父类的函数被覆盖一样
这种情况是函数的另一个特性:重写(覆盖,复写)
当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖,保留父类的功能定义,并重写功能内容
覆盖:
1.子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败
2.静态只能覆盖静态
3.构造函数
在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句 super()
super():会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super()
为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的.所以子类在对象初始化时,要先访问一下父类中的构造函数
如果要访问父类中指定的构造函数,可以通过手动定义super语句方式来指定
注意:super 语句一定定义在子类构造函数的第一行
子类的实例化过程:
结论:子类的所有构造函数,默认都会访问父类中空参数的构造函数,因为每一个子类构造函数内第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super形式来指定要访问父类中的构造函数
当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数
final:最终.
作为一个修饰符,
1.可以修饰类,函数,变量.
2.被final修饰的类不可以被继承,为了避免被继承,被子类复写功能
3.被final修饰的方法不可以被覆盖
4.被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读星,都给这些值起个名字,方便于阅读,而这个值不需要改变,所以加上final修饰.作为常量,常量的书写规范,所有字母都大写,如果由多个单词组成,单词间通过_连接
public static final 全局常量
5.内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量
当多个类中出现相同功能,但是功能主题不同,这时可以向上抽取,只抽取功能定义,而不抽取功能主体
抽象类的特点:
1.抽象方法一定在抽象类中
2.抽象方法和抽象类都必须被abstract关键字修饰
3.抽象类不可以用new创建对象,因为调用抽象方法没意义
4.抽象类中的方法要被使用,必须由子类复写所有的抽象方法后,建立子类对象调用,如果子类值覆盖了部分抽象方法,那么该子类还是一个抽象类
抽象类和一般类没有太大的不同.
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不得的东西,这些不确定的部分,也是该事物的功能,需要明确实现,但是无法定义主体,通过抽象方法来表示
抽象类比一般类多了抽象方法,就是可以定义抽象方法
抽象类不可以实例化
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让改类建立对象
/*
需求:获取一段程序运行的时间.
原理:获取程序开始的时间,并获取程序结束的时间,相减
获取时间:System.currentTimeMillis();
*/
abstract class GetTime
{
public final void getTime(){
long start = System.currentTimeMillis();
fun();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
abstract void fun();
}
class SubTime extends GetTime
{
public void fun(){
for(int i = 0;i<4000;i++){
System.out.print(i);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
GetTime gt = new SubTime();
gt.getTime();
}
}
/*
这种方式,就是模版方法设计模式,-->提高扩展性,复用性
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时候,就将不确定的部分暴露出去,由该类的子类去完成
*/
接口:初期,可以理解认为是一个特殊的抽象类
class用于定义类
interface 用于定义接口
接口定义时,格式的特点:
1.接口中常见定义: 常量,抽象方法
2.接口中的成员都有固定修饰符
常量:public static final -->可以省略
方法:public abstract -->可以省略
建议:为了增加阅读性,不建议省略
可以看出:接口中的成员都是public的
接口是不可以创建对象的,因为有抽象方法,需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类是一个抽象类
类实现接口关键字:implements
接口可以被类多实现.
类与类之间有继承关系,类与接口之间有实现关系,接口与接口之间是继承关系
所以java在接口与接口之间存在多继承关系
接口的特点:
接口是对外暴露的规则.
接口是程序的功能扩展
接口的出现降低了系统间的耦合度
---------------------------------
多态:可以理解为事物存在多种体现形态
人:男人,女人
动物:猫,狗
猫 cat = new 猫();
动物 animal = new 猫();
一个类中可以有多个方法以重载的方式存在也是多态的体现
java中主要说的是对象的多态性
1.多态的体现
父类引用指向子类对象
(父类引用可以接收子类对象)
2.多态的前提
必须类与类有关系,要么继承,要么实现
一般还有一个前提:存在覆盖
3.多态的好处
多态的出现提供了程序的扩展性
4.多态的弊端:
但只能使用父类的引用访问父类中的成员
5.多态的应用
6.多态的出现代码中的特点(多态使用的注意事项)
Animal a = new Cat();//类型提升,向下转型
如果想调用子类特有方法时,可以强制将父类的引用,转成子类类型,也叫向下转型
千万不要讲父类对象转成子类类型
我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换.多态自始至终都是子类对象做变化
在多态中成药函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,没有,则编译失败.
在运行时期:参阅对象所属的类中是否有调用的方法
简单总结就是:成员函数在多条调用时,编译看左边,运行看右边
在多态中,成员变量的特点
无论编译和运行,都参考左边(引用型变量所属的类)
在多态中,静态成员函数的特点:
无论编译和运行,都参考左边
给你个例子
class Fu {
int num = 5;
void method1() {
System.out.println("fu method_1");
}
void method2() {
System.out.println("fu method_2");
}
static void method3() {
System.out.println("fu method_3");
}
}
class Zi extends Fu {
int num = 8;
void method1() {
System.out.println("zi method_1");
}
static void method3() {
System.out.println("zi method_3");
}
}
public class C{
public static void main(String args[]) {
Fu f = new Zi();
System.out.println(f.num);//5
多态中成员变量的特点,
无论编译和运行,都参考左边(引用变量所属的类)
f.method1(); //zi method_1//覆盖
f.method2(); //fu method_2
多态中非静态函数的特点,
在编译时期:参阅引用类型变量所属的类中是否调用的方法,如有,编译通过,如没有,编译失败
在运行时期:参阅对象所属的类中是否有调用的方法
简单的总结就是:成员函数在多态调用时,编译看左边,运行看右边
f.method3(); //fu method_3
在多态中,静态成员函数的特点,
无论编译和运行,都参考左边
当静态方法一进内存,就已经绑定在所属的类上了(静态绑定)
}
}
Object:是所有对象的直接或者间接父类
该类中定义的肯定是所有对象都具备的功能
equals()
hashCode()
toString()
相关文章推荐
- JAVA基础知识点(六)--接口,多态,继承,抽象类,重载的问题
- 黑马程序员——Java基础---面向对象(继承、多态、抽象类、接口、内部类)
- JAVA中几个易混淆关键词的理解:行为,隐藏,组合和继承,覆写和重载,多形(多态)性,动态绑定,上溯造型,抽象类,接口
- 黑马程序员 Java面向对象(继承,抽象类,接口,多态,内部类)
- java 继承与多态之抽象类和接口
- Java基础笔记-继承、抽象类、接口、多态、内部类、异常
- 黑马程序员 Java基础 面向对象:继承、final关键字、抽象类、模版方法模式、接口、多态、Object类
- 黑马程序员-java学习继承之抽象类、多态和接口
- JAVA实验三 抽象类的继承和接口的实现 (多态)
- 黑马程序员——【Java基础】——面向对象(一)概述、类与对象、继承、抽象类、接口、多态、内部类
- java [继承]-[接口]-[抽象类]-[多态]-[Object]
- JAVA-6-继承、super、final、多态、抽象类、接口
- 关于JAVA继承、多态、抽象类、接口等性质的学习(3)
- 学习笔记_毕向东 Java_继承_抽象类_接口_多态 2014.7.13
- 黑马程序员——java基础——继承、抽象类、接口、多态
- 初识JAVA(【面向对象】:pub/fri/pro/pri、封装/继承/多态、接口/抽象类、静态方法和抽象方法;泛型、垃圾回收机制、反射和RTTI)
- Java类、属性、方法、对象、继承、多态、接口、抽象类...
- java基础(2)-基础类型和语法(static、内部类、final、抽象类、接口、封装)(并将这些基础知识与java的三大特征关联(继承、多态、封装))
- java的若干问题(1)——继承、多态、抽象类与接口
- java--抽象类与接口,继承与多态