黑马Java学习笔记之-----面向对象(二)
---------------------- android培训、java培训、期待与您交流! ----------------------
继承:
1、什么是继承?
子类会自动继承父类所有方法和属性。
2、继承的作用?
实现代码的复用性。
让类与类之间产生关系。有啦关系才有多态特征
注意:
不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。所属关系 is a(子类是父类的一种)。
一个孩子只能有一个父亲!
子父类出现后,类成员的特点:
类中成员:
1,变量。
2,函数。
3,构造函数。
变量
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super。
super的使用和this的使用几乎一致。
this代表的是本类对象的引用。
classFu { int num=4; public void setNum(int num) { this.num=num; } public int getNum() { return this.num; } } classZi extends Fu { int num=5; void show() { System.out.println(super.num); } } class ExtendsDemo2 { public static void main(String[] args) { Zi z=new Zi(); z.show(); System.out.println(z.num+"..."+z.num); } }
子父类中的构造函数:
在对子类对象进行初始化时,父类的构造函数也会运行,
那是因为子类的构造函数默认第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();
为什么子类一定要访问父类中的构造函数。
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
注意:super语句一定定义在子类构造函数的第一行。
子类的实例化过程。
结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类每一个构造函数内的第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。
class Fu { int num; Fu() { num=60; System.out.println("furun"); } Fu(int x) { System.out.println("furun!!"+x); } } classZi extends Fu { Zi() { //super(); super(3); System.out.println("zirun"); } Zi(int x) { this(); //super(); System.out.println("zi..."+x); } } classExtendsDemo4 { public static void main(String[] args) { Zi z=new Zi(); //Zi z1=new Zi(4); System.out.println(z.num); } }
final:最终,修饰符。
1 可以修饰类,函数,变量。
2 可以被final修饰的类不可以被继承。为了避免被继承,被子类复写自己的功能。
3 被final修饰的方法不可以被复写。
4 被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性。都可以给这个值起个名字,方便于阅读。 而这个值不需要改变,所以加上final修饰。
作为常量,常量的书写规范,所有字母都大写,如果有多个单词组成,单词间通过_连接。
5 内部类,定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
需求:获取一段程序运行的时间。
原理:获取程序开始和结束的时间并相减即可。
获取时间:system。currentTimeMillis();
当代码完成优化后,就可以解决这类问题。
这种方式,模板方法设计模式。
1 abstractclass GetTime 2 3 { 4 5 public final void getTime(String[] args) 6 7 { 8 9 long start=System.currentTimeMillis(); 10 11 12 runcode(); 13 14 longend=System.currentTimeMillis(); 15 16 System.out.println("毫秒"+(end-start)); 17 18 } 19 20 public abstract void runcode(); 21 22 } 23 24 classSubTime extends GetTime 25 26 { 27 28 public void runcode() 29 30 { 31 32 for (int x=0;x<4000 ;x++ ) 33 34 { 35 36 System.out.print(x); 37 38 } 39 40 } 41 42 }
多态:可以理解为事物存在的多种体现形态。
1,多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。
3,多态的好处
多态的出现大大的提高程序的扩展性。
4,多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5,多态的应用
6,多态的出现代码中的特点(多态使用的注意事项)
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
例题:
基础班学生:
学习,睡觉。
高级班学生:
学习,睡觉。
可以将这两类事物进行抽取。
abstract class Student { public abstract void study(); public void sleep() { System.out.println("躺着睡"); } } class DoStudent { public void doSome(Student stu) { stu.study(); stu.sleep(); } } class BaseStudent extends Student { public void study() { System.out.println("base study"); } public void sleep() { System.out.println("坐着睡"); } } class AdvStudent extends Student { public void study() { System.out.println("adv study"); } public void sleep() { System.out.println("躺着睡"); } } class DuoTaiDemo2 { public static void main(String[] args) { DoStudent ds=new DoStudent(); ds.doSome(new AdvStudent()); ds.doSome(new BaseStudent()); } }
Implements
是一个类实现一个接口用的关键字,他是用来实现接口中定义的抽象方法。
还有几点需要注意:
(1)接口可以被多重implements,抽象类只能被单一extends
(2)接口只有定义,抽象类可以有定义和实现
(3)接口的字段定义默认为:public static final, 抽象类字段默认是"friendly"(本包可见)
与Extends的区别
extends,可以实现父类,也可以调用父类初始化 this.parent()。而且会覆盖父类定义的变量或者函数。这样的好处就是架构师定义好接口,让工程师实现就可以了。整个项目开发效率得到提高,且开发成本大大降低。
implements,实现父类,子类不可以覆盖父类的方法或者变量。即使子类定义与父类相同的变量或者函数,也会被父类取代掉。
两种实现的具体使用,是要看项目的实际情况,需要实现,不可以修改implements,只定义接口需要具体实现,或者可以被修改扩展性好,用extends。
Object:
是所有对象的直接后者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能。
Object类中已经提供了对对象是否相同的比较方法。
如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。
---------------------- android培训、java培训、期待与您交流! ----------------------