【黑马程序员】多态、抽象类、接口——Java复习笔记
2015-11-04 00:47
435 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
final关键字
A:它修饰的类,不能被继承。 B:它修饰的方法,不能被重写。 C:它修饰的变量,是一个常量(自定义常量 ),不能被重新赋值(基本类型:值。引用类型:地址值)。 面试相关: A:final修饰局部变量 a:基本类型 值不能发生改变 b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的 B:final修饰变量的初始化时机 a:被final修饰的变量只能赋值一次。 b:在构造方法完毕前
多态
(1)同一个对象在不同时刻体现出来的不同状态。 (2)多态的前提: A:有继承或者实现关系。 B:有方法重写。 C:有父类或者父接口引用指向子类对象。即: 父 f = new 子(); (3)多态中的成员访问特点 A:成员变量 编译看左边(父 f),运行看左边 父 f = new 子(); 都只访问父类的成员变量 B:构造方法 子类的构造都会默认访问父类构造 C:成员方法 编译看左边,运行看右边(new 子) 编译的时候只看父类有没有该方法。运行的时候运行的是子类重写的该方法 D:静态方法 编译看左边,运行看左边(所以重写静态方法算不上重写,因为静态和类相关,访问的时候还是访问左边) 结论:因为成员方法有重写,所以运行看右边。 (4)多态的好处: A:提高代码的维护性(继承体现) B:提高代码的扩展性(多态体现) (5)多态的弊端: 父不能使用子的特有功能。若要使用子类特有功能,要么创建子类对象;要么把父类引用强转为子类引用,即向下转型Zi z = (Zi)f; 即子可以当作父使用,父不能当作子使用。 (6)多态中的转型 A:向上转型 从子到父 B:向下转型 从父到子
抽象类
(1)把多个共性的东西提取到一个类中,这是继承的做法。 但是呢,这多个共性的东西,每个具体的对象在具体实现的时候内容不一样。 所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。 而一个没有方法体的方法是抽象的方法。public abstract void eat(); 在一个类中如果有抽象方法,该类必须定义为抽象类。 (2)抽象类的特点 A:抽象类和抽象方法必须用关键字abstract修饰 B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类 C:抽象类不能实例化。可以通过多态的方式实例化 D:抽象类的子类 a:是一个抽象类。不重写抽象方法 b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。 (3)抽象类的成员特点: A:成员变量 有变量,有常量 B:构造方法 有构造方法。用于子类访问父类数据的初始化 C:成员方法 有抽象,有非抽象 抽象方法:强制要求子类做的事情 非抽象方法:子类继承的事情,提高代码复用性 (5)抽象类的几个小问题 A:抽象类有构造方法,不能实例化,那么构造方法有什么用? 用于子类访问父类数据的初始化 B:一个类如果没有抽象方法,却定义为了抽象类,有什么用? 为了不让创建对象 C:abstract不能和哪些关键字共存 a:final 冲突 不能被重写 b:private 冲突 private不能被继承 c:static 无意义 因为抽象方法无方法体 静态可以通过类名访问 访问一个没有方法体的方法无意义
接口
需要额外的功能,java提供了接口表示。 (1)接口的特点: A:接口用关键字interface修饰 interface 接口名 {} B:类实现接口用implements修饰 class 类名 implements 接口名 {} C:接口不能实例化 D:接口的实现类 a:是一个抽象类。 b:是一个具体类,这个类必须重写接口中的所有抽象方法。 (2)接口的成员特点: A:成员变量 只能是常量(都默认为常量)并且是静态的 默认修饰符:public static final B:构造方法 没有构造方法 C:成员方法 只能是抽象方法 默认修饰符:public abstract (3)类与类,类与接口,接口与接口 A:类与类 继承关系,只能单继承,可以多层继承 B:类与接口 实现关系,可以单实现,也可以多实现。 还可以在继承一个类的同时,实现多个接口 C:接口与接口 继承关系,可以单继承,也可以多继承 (4)抽象类和接口的区别 A:成员区别 抽象类:常量变量都行。有构造方法。成员方法可抽象可非抽象 接口:都是常量。无构造方法。成员方法只可抽象 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法; B:关系区别: 类与类:继承 类与接口:实现 接口与接口:继承,可单可多 C:设计理念不同 抽象类:is a,抽象类中定义的是共性功能。 接口:like a,接口中定义的是扩展功能。 简单来说,接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的, 另外,实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。 从设计层面上看 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。 抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
形式参数和返回值的问题
(1)形式参数: 类名:需要该类的对象 抽象类名:需要该类的子类对象,其本身不能被实例化 接口名:需要该接口的实现类对象 (2)返回值类型: 同上 (3)链式编程 对象.方法1().方法2().......方法n(); 注意:方法1()、方法2()……方法n-1()每个方法调用完毕后,都是返回一个对象
包
(1)作用:A:区分同名的类 B:对类进行分类管理 a:按照功能分 b:按照模块分 (2)注意事项: A:package语句必须在文件中的第一条有效语句 B:在一个java文件中,只能有一个package C:如果没有package,默认就是无包名 (3)带包的编译和运行 javac -d . HelloWorld.java // .代表在当前目录下生成文件夹 (4)导包 import 包名...类名; package,import,class的顺序:package > import > class
修饰符
(1)权限修饰符
修饰符 | 本类 | 同一个包下的类 | 不同包下的子类 | 不同包下的无关类 |
---|---|---|---|---|
private | Y | |||
默认 | Y | Y | ||
protected | Y | Y | Y | |
public | Y | Y | Y | Y |
这四种权限修饰符在任意时刻只能出现一种。 (2)常见修饰符分类: 权限修饰符:private,默认,protected,public 状态修饰符:static,final 抽象修饰符:abstract (3)常见的类及其可用的修饰符 类: 默认,public,final,abstract 常用的:public 成员变量: 除了abstract,都可以 常用的:private 构造方法: 只能用访问权限修饰符 常用的:public 成员方法: 都可以 常用的:public
内部类
(1)内部类的特点 A:可以直接访问外部类的成员,包括私有 B:外部类要想访问内部类成员,必须创建对象 (2)内部类的分类 A:成员内部类 B:局部内部类 (3)成员内部类 A:private 为了数据的安全性 B:static 为了访问的方便性 静态一般不合private一起用 静态内部类访问的外部数据必须也是静态的 成员内部类不是静态的: Outer.Inner 对象名 = new Outer.new Inner(); 成员内部类是静态的: Outer.Inner 对象名 = new Outer.Inner(); (4)成员内部类的面试题 内部类和外部类没有继承关系 需求:输出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);//访问外部类的成员变量 } } }
(5)局部内部类 A:在局部位置,可创建内部类对象,通过对象调用内部类方法,来使用局部内部类的功能 B:局部内部类访问局部变量必须加final修饰。 因为局部变量使用完毕就消失,而堆内存的数据并不会立即消失。所以,堆内存还是用该变量,而该变量已经没有了。为了让该值还存在,就加final修饰。通过反编译工具我们可以看到,加入final后,堆内存直接存储的是值,而不是变量名。 (6)匿名内部类 A:是局部内部类的简化形式 B:前提:存在一个类或者接口 C:格式: new 类名或者接口名() { 重写方法; }; //这一整个是一个对象 D:本质: 其实是继承了该类或者实现了该接口的子类匿名对象 但是创建一个匿名内部类后只能调用一次方法,若想调用多个方法,就用多态的方法将该匿名内部类赋值给该类或接口 Inter i = new Inter(){Override}; i.show1(); i.show2(); (7)匿名内部类应用
interface Person { public abstract void study(); } class PersonDemo { public void method(Person p) { p.study(); } } class PersonTest { public static void main(String[] args) { PersonDemo pd = new PersonDemo(); pd.method(new Person() { public void study() { System.out.println("好好学习,天天向上"); } }); } } //例2: interface Inter { void show(); } class Outer { public static Inter method() { //返回的是Inter实现对象 //匿名内部类 return new Inter() { //重写show方法 public void show() { System.out.println("HelloWorld"); } }; } } class OuterDemo { public static void main(String[] args) { Outer.method().show(); //"HelloWorld" //匿名内部类创建对象后直接调用show方法 new Inter(){ public void show(){ System.out.println("helloworld"); } }.show(); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统