黑马程序员——JAVA学习笔记四(继承、接口、内部类)

1,    通过extends关键字让类与类之间产生继承关系。多个类中存在相同属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需定义这些属性和行为,只要继承那个类即可,已存在的类叫做超类,基类,或父类。新类称为子类,派生类,孩子类。

子类可以直接访问父类中的非私有的属性和行为。子类无法继承父类中私有的内容。JAVA不支持多继承,只支持单继承,多实现。

继承提高了代码复用性,让类与类之间产生了关系。为多态提供了前提。

2,    super关键字代表父类中成员变量内存空间的标示。两个作用:调用超类的方法或变量,2,调用超类的构造器。

3,    覆盖,当子父类中出现的成员函数一模一样的情况,会运行子类的函数。这种现象叫做,覆盖操作。当子类需要父类的功能,而功能主体子类有自己的特有内容时,可以复写父类的方法。注意覆盖和重载的区别。父类私有方法和static方法不可以覆盖,只是隐藏了。覆盖时,子类的方法权限一定要大于等于父类权限。允许子类将覆盖方法的返回类型定义为原返回类型的子类型。

3,       构造函数,子类中构造函数默认调用子类默认构造函数。先初始化子类,然后才是父类。父类构造函数必须放在第一行。对象初始化顺序,如下:

一个对象实例化过程,以Person p = new Person();为例:

1、JVM会读取指定的路径下的Person.class文件,并加载进内存,并会先加载Person的父类(如果有直接的父类的情况下)。

2、在内存中开辟空间,并分配地址。

3、并在对象空间中,对对象的属性进行默认初始化。

4、调用对应的构造函数进行初始化。

5、在构造函数中,第一行会先到调用父类中构造函数进行初始化。

6、父类初始化完毕后,再对子类的属性进行显示初始化。

7、再进行子类构造函数的特定初始化。

8、初始化完毕后,将地址值赋值给引用变量。

4,    final关键字:

final可以修饰类,方法,变量。

final修饰的类不可以被继承。

final修饰的方法不可以被覆盖。

final修饰的变量是一个常量,只能被赋值一次。

为什么要用final修饰变量,其实在程序中如果一个数据是固定的。

那么直接使用这个数据就可以了,但是这种阅读性差,所以应该给数据起个名称。

而且这个变量名称的值不能变化,所以加上final固定。

写法规范:常量所有字母都大写,多个单词,中间用_连接。

5,    抽象类,抽象就是从多个事物中将共性的内容提取出来。JAVA可以定义没有方法的体的方法,该方法的具体实现有子类完成,该方法称为抽象方法,该类称为抽象类。抽象类和抽象方法必须用abstract关键字来修饰。

抽象类是从具体事物抽取而来,本身不是具体的,没有对应的实例,不能被实例化。 抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。

抽象类中是否有构造函数?

答:有,用于给子类对象进行初始化。

抽象关键字abstract不可以和哪些关键字共存?

答:private、static、final。

final:不可以在子类定义覆盖其方法。

抽象类中可不可以没有抽象方法?

答:可以,但是很少见。目的就是不让该类创建对象,AWT的适配器对象就是这种类。通常这个类中的方法有方法体,但是却没有内容。

相同点:

抽象类和一般类都是用来描述事物的,都在内部定义了成员。

不同点:

①一般类有足够的信息描述事物。

抽象类描述事物的信息有可能不足。

②一般类中不能定义抽象方法,只能定义非抽象方法。

抽象类中可定义抽象方法,同时也可以定义非抽象方法。

③一般类可以被实例化。

抽象类不可以被实例化。

6,    接口,

当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用另一种形式定义和表示,就是接口。

①虽然抽象类中的全局变量和抽象方法的修饰符都可以不用写,但是这样阅读性很差。所以,最好写上。

②类与类之间是继承关系,类与接口直接是实现关系。

③接口不可以实例化,只能由实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化。否则,这个子类就是一个抽象类。

抽象类和接口的异同点?

相同点:
都是不断向上抽取而来的。
不同点:
①抽象类需要被继承,而且只能单继承。
   接口需要被实现,而且可以多实现。
②抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。
   接口中只能定义抽象方法,必须由子类去实现。
③抽象类的继承,是is a关系,定义该体系的基本共性内容。
   接口的实现是like a关系。

7,    多态,一个对象变量可以指示多种实际类型的的现象称为多态。是"IS -A“规则。

体现:
父类或者接口的引用指向或者接收自己的子类对象。
作用:
多态的存在提高了程序的扩展性和后期可维护性。

前提:
①需要存在继承或者实现关系。
②需要有覆盖操作。

好处:

提高了代码的扩展性,前期定义的代码可以使用后期的内容。
弊端:
        前期定义的内容不能使用(调用)后期子类的特有内容。

JAVA中,子类数组引用可以转化为超类数组引用,不需要强制类型转换,但是需要注意,时时刻刻记住创建数组的类型。

instanceof :用于判断对象的具体类型,只能用于引用数据类型判断,通常在向下转型前用于健壮性的判断,NULL不会报错。

 

成员变量
     编译时:参考引用型变量所属的类中的是否有调用的成员变量。有,编译通过,没有,编译失败。
     运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。
     简单说:编译和运行都参考等号的左边。

成员函数(非静态)
     编译时:参考引用型变量所属的类中是否有调用的函数。有,编译通过。没有,编译失败。
     运行时:参考的是对象所属的类中是否有调用的函数。
     简单说:编译看左边,运行看右边。

静态函数
     编译时:参考的是对象所属的类中是否有调用的函数。
     运行时:参考的是对象所属的类中是否有调用的函数。
     简单说:编译和运行看左边。

8,    动态绑定,对象方法调用时步骤,候选方法->重载解析->调用。

如果是private方法,static方法,final方法或者构造器,那么编译器将可以准确的知道应该调用那个方法,这种调用方式叫做静态绑定。与此对应的是,调用的方法依赖于隐式的参数类型,并且在运行时实现动态绑定。编译器采用动态绑定的方式生成一条调用其方法的指令。当程序运行,并且采用动态绑定调用方法时,虚拟机一定调用与X所引用对象的实际类型最合适的那个方法。

每次调用方法都要进行搜索,时间开销相当大,因此,虚拟机预先为每个类创建了一个方法表,其中列出了所有方法的签名和实际调用的方法。

9,Object类,所有类的超类,  用==比较基本类型, equals比较对象域,比较两个对象是否具有相同的引用。

equals()方法:自反性(x!=null, x.equals(x)=ture),对称性( x.equals(y)= y.equals(x) ),传递性(x=y, y= z, 则 x=z),一致性(如果引用对象没有发生变化,则结果也不会变),如果子类能拥有自己的相等概念。则对称性需求将强制采用getClass进行检测。如果超类决定相等的概念,那么就可以用instanceof进行检测,这样可以用于不同子类进行相等检测。@override防止没有覆盖父类方法。

hashcode()方法,有对象导出的一个整形值。默认是对象的存储存地址。String中是有内容组成的。如果重新定义equals方法,则也需要重新定义hashCode方法。他们的定义必须一致。

clone()方法,深拷贝则需要用clone()方法,他是protect方法,用户不能直接调用它。一般情况下:如果要深拷贝,必须要重新定义clone方法。

对于每一个类,需要作以下判断:

1, 默认的clone方法是否满足需求。

2,默认的clone方法是否能够通过调用可变子对象的clone得到修补。

3, 是否不应该使用clone。

要选择1或者2,则:

实现Cloneable接口。(该接口仅起一个标记作用,如果一个对象需要克隆,而没有实现cloneable接口,则会抛出一个异常。现在可以返回object类的子类,斜边返回类型)

使用public访问修饰符重新定义clone方法。

10,    对象包装器,Integer ,Long, Double, Float, Short, Byte,Chararter,Void, Boolean(前6个派生于Number类)。装箱:XXX.valueOf() 拆箱:XXX.xxvalue(),自动装箱规范要求boolean,byte,char<= 127. 介于-128~127之间的short 和int被包装到固定的对象中。

11,    可变参数,当成数组使用。

枚举类:可以直接用==比较,不需要equals比较。如果需要,可以在枚举类中添加一些构造器、方法和域。当然,构造器只是在构造枚举常量是被调用。所有的枚举类型都是Enum类的子类,常用方法toSTring()。valueOf(class, string), values().

12,    接口与回调,回调是一种常见的程序设计模式,在这种模式中,可以指出某个特定事件。由于对象可以携带一些附加的信息,所以传递一个对象比传递一个函数要灵活得多。

13,    内部类,将一个类定义在另一个类的里面,里面那个类就称为内部类(内置类,嵌套类)。

为什么要使用内部类?

内部类可以直接访问外部类中的成员,包括私有成员。

内部类可以对同一个包中的其他类隐藏。

当要定义一个回调函数不想写大量的代码,使用匿名内部类比较便捷。

对外部类的引用:outer.this

在外部类作用域之外,可以这样使用内部类:outerclass.innerclass

编译器会把内部类翻译成用$分割外部类名和内部类名的常规类文件。

编译器会生成this$0的变量外部对象引用。所有的名字都会加上outer$。

内部类访问外部类私有域,会在外部类生成一个静态方法。。这样有安全隐患。同时还会生成构造器。

内部类定义在成员位置上,可以被private、static成员修饰符修饰。被static修饰的内部类只能访问外部类中的静态成员。

如果内部类中定义了静态成员,该内部类也必须是静态的!

内部类定义在局部位置上,也可以直接访问外部类中的成员。局部类修饰符不能用public private 访问说明符号进行申明,可以对外部世界完全隐藏起来,即使外部类方法也不能访问。

同时可以访问所在局部中的局部变量,但必须是被final修饰的。内部类会备份final常量和外部类this。

为了保持局部变量和局部在内部类拷贝的一致。

匿名内部类:

定义:

就是内部类的简化写法。
前提:
内部类可以继承或实现一个外部类或者接口。
格式:
new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}

简单理解:
就是建立一个带内容的外部类或者接口的子类匿名对象。

什么时候使用匿名内部类呢?
通常在使用方法是接口类型参数,并且该接口中的方法不超过三个时,可以将匿名内部类作为参数传递。

由于构造器的名字必须和类名一致,而匿名类没有类名,所以,匿名类不能有构造器,取而代之将构造器传递给超类构造器。

声明在接口中的内部类默认自动为public和Static.

技巧:双括号初始化。

ArrayList<String> friends = new ArrayList();

friends.add("nihao");

friends.add("hell:");

invite(friends);

可简化为:invite(new ArrayList<String>(){{ add("Hary"); add("Tony"); }});    构造代码块。

时间: 2024-12-23 00:28:25

黑马程序员——JAVA学习笔记四(继承、接口、内部类)的相关文章

黑马程序员——JAVA学习笔记十四(高新技术三)

10 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代

黑马程序员——JAVA学习笔记十(IO)

1,    可以从其中读入一个字节序列的对象成为输入流,可以向其中写入一个字节序列的对象就做输出流.这些字节序列的来源地可以是文件,也可以是网络连接或者内存块.抽象类InputStream和OutputStream构成了I/O层次的基础.因为字节流不便于处理以Unicode存储的信息,所以有了Writer和Reader抽象类,这些从其中继承的类都是读入和写入基于2个字节的Unicode码元,而不是单个字节.   2,    InputStream 与OutputStream: abstract

黑马程序员——JAVA学习笔记五(异常)

1,     异常:是在运行时期发生的不正常情况. 在java中用类的形式对不正常情况进行了描述和封装对象.描述不正常的情况的类,就称为异常类. 以前正常流程代码和问题处理代码相结合,现在将正常流程代码和问题处理代码分离,提高阅读性. 其实异常就是java通过面向对象的思想将问题封装成了对象,用异常类对其进行描述. 不同的问题用不同的类进行具体的描述.比如角标越界.空指针异常等等. 问题很多,意味着描述的类也很多,将其共性进行向上抽取,形成了异常体系. 不正常情况分成了两大类: Throwabl

黑马程序员——JAVA学习笔记十三(高新技术二)

8,    注解 Annotation(注解)是JDK5.0及以后版本引入的. 注解是以 @注解名 的形式标识 注解不会影响程序语义,只作为标识 注解是新的类型(与接口很相似),它与类.接口.枚举是在同一个层次,它们都称作为java的一个类型(TYPE). 它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释. 它的作用非常的多,例如:进行编译检查.生成说明文档.代码分析等 注释类型 是一种特殊的接口 用 @interface 声明如 [email prote

黑马程序员——JAVA学习笔记十二(高新技术一)

 1,    静态导入: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.solaire.enhance; import static java.lang.Math.max;  //import   语句可以导入一个类或某个包中的所有类 //import static  静态导入 JDK5以后才有.语句导入一个类中的某个静态方法或所有静态方法 //无名包和有包名中的类在一起,没有package,则为无名包. //一个类

黑马程序员——JAVA学习笔记八(集合)

1,    JAVA最初版本只为最常用的数据结构提供了很少的一组类:Vector.Stack.Hashtable.BitSet与Enumeration接口,从JAVA1.2版本开始推出了一组功能完善的的数据结构. 集合类的由来:  对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定.  就使用集合容器进行存储. 集合特点: 1,用于存储对象的容器. 2,集合的长度是可变的. 3,集合中不可以存储基本数据类型值. 4,接口与实现相互分离. 集合框架是为表示和操作集合而规定的一种统一的标准

黑马程序员——JAVA学习笔记六(多线程)

1,    什么是多线程?一个程序可以执行多个任务,每一个任务称为一个线程,运行多个线程的程序称为多线程程序. 进程:正在进行中的程序(直译). 线程:进程中一个负责程序执行的控制单元(执行路径).   多线程的好处:解决了多部分代码同时运行的问题.多线程的弊端:线程太多,会导致效率的降低. 其实,多个应用程序同时执行都是CPU在做着快速的切换完成的.这个切换是随机的.CPU的切换是需要花费时间的,从而导致了效率的降低 2 ,    创建线程方式:  创建线程方式一:继承Thread类 1.定义

黑马程序员——JAVA学习笔记三(面向对象)

1,    面向对象设计程序(oriented object pragraming)  ,其程序是有对象组成,只要对象能满足要求,就不需要关心其功能的具体实现.面向对象的特征:封装(encapsulation)继承(inherence)多态(polymorphism). 2,    类是对事物的属性和行为的描述,构造对象的模板和蓝图.对象是类的实例,它具有三个特征:行为(behavior)状态(state) 对象标示(identity如何辨别具有相同状态和行为的对象).成员函数默认有一个隐含参数

黑马程序员——JAVA学习笔记二(语法基础)

1,     Java程序都是以类的形式存在的,所以需要告诉虚拟机需要加载类的位置,那么可以设置classpath变量.classpath变量如果有;,则表示还会在当前目录查找,没有;则不会在当前目录查找. 当然如果没有classpath也会在当前目录查找. 2,    rd删除目录,加/S可以删整个目录,Windows从里向外删除. 3,    一个文件只有一个public类,文件名必须和类名相同,如果不是友好类,则不需要同名. 4,    JAVA一共有50个关键字 关键字是电脑语言里事先定