黑马程序员---java基础----面向对象总结
2015-09-24 16:45
746 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
一、面向对象思想:
面向过程:关注步骤和过程
面向对象:关注的是对象
面向对象是基于面向过程的
(1)类的定义
手机事物:属性:
品牌 , 颜色 , 价格 .....行为:
打电话 , 发短信 , 打游戏 ....手机类:成员变量:
品牌(brand) , 颜色(color) , 价格(price) 成员方法: 打电话(call) , 发短信(sendMessage) , 打游戏(playGame)
(2)类与对象
我们学习编程的目的? 为了模拟现实生活中的事物 .
如何描述现实生活中的事物呢?
学生:
姓名,年龄, 性别 ....
学习 , 吃饭 , 睡觉 ....
属性: 就是事物的描述信息
行为: 就是该事物可以做什么事情
而我们java语言的最小单位是一个类. 所以我们就找到了事物是java语言中的一个东西的对应关系.
事物类
属性 成员变量
行为 成员方法
成员变量: 和之前定义变量一样,只不过位置不同,在类中方法外
成员方法: 和之前定义方法一样,只不过去掉static(后面在讲解)
类: 是一组相关属性和行为的集合, 类是一个抽象的东西
对象: 就是该类的一个具体体现
举例:
学生 类
班长 对象
使用类:
创建对象: 格式:
类名 对象名 = new 类名();
访问成员变量的格式:
对象名.变量名 ;
访问成员方法的格式:
对象名.方法名(...)
创建对象的步骤:
Student s = new Student();
步骤:
(1): 加载Student的字节码文件到方法区
(2): 在栈内存中为s开辟空间
(3): 在堆内存中为new Student()开辟空间
(4): 给成员变量进行默认初始化
(5): 给成员变量进行显式初始化
(6): 通过构造方法对成员变量赋值
(7): 将堆内存中的地址值赋值给栈内存中的引用变量s
(3)一个对象的内存图
![](http://img.blog.csdn.net/20150924165148643)
(4)局部变量和成员变量的区别:
a: 在类中的位置不同
局部变量: 在方法定义中或者方法声明上的变量
成员变量: 在类中方法外
b: 在内存中的位置不同
成员变量: 在堆内存
局部变量: 在栈内存
c: 生命周期不同
成员变量: 随着对象的创建而产生,随着对象的消失而消失
局部变量: 随着方法的调用而产生,随着方法的消失而消失
d: 初始化值的问题:
成员变量: 有默认值(系统给定)
局部变量: 没有默认值,必须对其赋值以后才能使用
变量的注意事项:
a: 局部变量可以和成员变量的名称一致
b: 变量在访问的时候,遵循一个原则"就近原则"
(5)java语言中的参数传递问题:
基本数据类型的参数传递,形式参数的改变对实际参数没有影响
引用数据类型的参数传递,形式参数的改变对实际参数是有直接影响的
引用数据类型: 数组 , 类 , 接口
如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
(6)匿名对象: 就是没有名字的对象
匿名对象的作用:
a: 调用方法,仅仅调用一次的时候
b: 作为参数传递
二、面向对象的3个特征:
封装
继承
多态
面向对象开发
就是不断的创建对象,使用对象,指挥对象做事情。
(1)封装
我们在赋值的时候,发现有时候可以为负数.但是我们都知道年龄不能为负数.所以我们应该对数据做一个校验吧.
我们需要将校验放在Student类中还是PrivateDemo类中?应该放在Student类中.为什么呢?
PrivateDemo 是一个测试类,既然是测试类,那么我们就需要测试所有的数据,而不能将错误的数据进行过滤吧.
校验: 我们需要使用一个逻辑的判断.所以我们需要使用语句.语句只能写在方法中,所以我们需要在Student类中
编写一个方法.(作用: 是给age设置值)
我们在使用的时候,我们还可以通过成员变量直接对其赋值.这样不太友好.
我们需要其强制的使用方法来对age设置.言下之意,就是不能让外界直接访问成员变量age.
这时候java就给我们提供了一个关键字: private (私有的)
封装的思想:
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
封装好处
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性。
封装原则
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问
a、private关键字的特点:
a: private是一个修饰符
b: 可以用来修饰成员变量和成员方法
c: 被private修饰的成员只能在本类中访问
b、this关键字:
我们在起名字的时候,要做到的"见名知意",但是现在没有做到"见名知意",所以我们需要更改一下下.
this关键字: 代表的是本类对象的一个引用, 谁调用我this就代表谁.
this的存在解决的问题: 当局部变量将成员变量隐藏的时候,我们就可以通过this来明确直接访问的是成员变量.
变量在访问的时候遵循一个就近原则,现在我们的局部变量的名称和成员变量的名称一致.
所以在赋值的时候,并没有涉及到成员变量.
而我们的目的是: 把传递进来的name赋值为成员变量的name
我们访问成员变量只能通过对象来进行访问,那么谁有可以代表当前类的一个对象呢?
这时候java就给我们提供了一个关键字: this
c、构造方法
特点:
(1): 方法名和类名相同
(2): 没有返回值类型,连void也没有
(3): 没有返回值
作用:
给成员变量赋值
注意事项:
(1): 当我们没有给出构造方法的时候,系统将会提供一个默认的无参的构造方法
(2): 当我们给出构造方法的时候,系统将不会提供一个默认的无参的构造方法
d、static关键字
特点:
(1): 随着类的加载而加载
(2): 优先于对象存在
(3): 被类的所有的对象所共享
(4): 可以通过类名调用.本身也可以通过对象名调用
建议使用类名调用
注意事项:
(1): 在静态的方法中不能存在this关键字
(2): 静态只能访问静态
e、代码块
概述: 在java中使用{}括起来的内容
分类: 局部代码块 , 构造代码块 , 静态代码块 , 同步代码块(多线程)
局部代码块:
位置在方法定义中
构造代码块: 位置在类中方法外 , 特点: 每创建一次对象都调用一次 , 并且优先于构造方法执行
静态代码块:
位置在类中方法外 , 前面添加一个static 特点: 随着类的加载而加载,只执行一次 ,优先于构造代码块
(2)继承
格式:class 子类名 extends 父类名 {}
好处:
(1): 提高了代码的复用性
(2): 提高了代码的维护性
(3): 让类与类产生了关系,是多态的前提
弊端:
让类与类产生了关系,增强了耦合性
特点:
(1): 只能是单继承 ,不能是多继承
(2): 可以使用多层继承
注意事项:
(1): 父类中私有的成员不能被子类继承
(2): 父类中的构造方法不能被子类继承,但是可以通过super去访问
(3): 不能为了部分功能去使用继承
继承中成员变量的访问特点:
变量在访问的时候遵循一个"就近原则"
查找顺序:
(1): 在子类的局部位置
(2): 在子类成员位置
(3): 在父类的成员位置找
(4): 报错
this和super的区别:
this: 表示是本类对象的一个引用,谁调用我this就代表谁
super:表示的是父类存储空间的一个标识(理解: 父类对象的运用)
成员访问格式:
成员变量
this.变量名
本类的成员变量
super.变量名
父类的成员变量
构造方法
this(...)
本类的构造方法
super(...)
父类的构造方法
成员方法
this.方法名(...) 本类的成员方法
super.方法名(...)父类的成员方法
继承中构造方法的访问特点:
子类在初始化的时候,默认去调用父类的无参的构造方法
所有的构造方法的第一句都是super()
注意事项:
this(...) 和 super(...)必须是构造方法第一行
Object:
所有的类都是直接的或者间接的继承自该类
继承中成员方法的访问特点:
查找顺序:
(1): 在子类中查找
(2): 在父类中查找
(3): 报错
方法重写与方法重载的区别
方法重写: 子类中出现了和父类中一模一样的方法(方法名, 返回值类型 , 参数列表)
方法重载: 在同一个类中,允许同时存在一个以上的同名方法只要它们的参数列表不同, 与返回值无关
final关键字
特点:
final(最终的)
修饰类 被修饰的类不能被继承
修饰变量 被修饰的变量其实是一个常量
引用类型 指的是地址值不能被改变
基本类型 指定是值不能被改变
修饰方法 被修饰的方法不能被子类重写
final的初始化时机问题:
a: 只能被赋值一次
b: 在构造方法结束前赋上值就OK了(非静态的)
(3)多态
前提:
(1): 需要有继承
(2): 需要有方法重写,没有方法重写也是可以的,但是没有意义
(3): 父类的引用指向子类对象
Fu f = new Zi();
多态中成员的访问特点:
成员变量: 编译看左边, 运行看左边
成员方法: 编译看左边 , 运行看右边
静态成员方法:
编译看左边 , 运行看左边
好处:
(1): 提供了代码的维护性(继承)
(2): 提供了代码的扩展性(多态)
弊端:
不能访问子类特有的功能
向下转型: 就是把父类的引用强制转换成子类的引用Zi zi = (Zi)f ;
向上转型: 父类的引用指向子类对象Fu f = new Zi();
抽象类
特点:
(1): 抽象类格式:
abstract class 类名 {}
抽象方法的格式:
public abstract 返回值类型 方法名(...);
(2): 抽象类中可以有非抽象方法,也可以有抽象方法,如果一个类中存在抽象方法,那么就需要将该类定义为抽象类
(3): 构造方法
有, 用于子类在访问数据的时候初始化
(4): 抽象类不能对其进行直接实例化,但是可以对其进行间接的实例化(多态的形式)
(5): 抽象类的子类
a: 可以是抽象类
b: 可以是具体的类,但是这个具体的类需要重写抽象类中的抽象方法
成员特点:
(1): 成员变量可以是变量,也可以是常量
(2): 构造方法有 , 用于子类在访问数据的时候初始化
(3): 成员方法可以是抽象方法,可以是非抽象方法
面试题:
abstract不能和那些关键字进行共存?
private冲突
final冲突
static无意义
接口
特点:
(1): 定义接口的格式
interface 接口名{}
(2): 类实现接口的格式
class 类名 implements 接口名{}
(3): 接口不能对其进行直接的实例化,但是可以通过多态的形式对其进行间接的实例化
(4): 接口的子类
a: 可以是抽象类
b: 可以是非抽象类,该类必须重写接口中的抽象方法
(5): 接口中没有构造方法,并且接口中的方法都是抽象方法
成员特点:
成员变量 只能常量,存在默认的修饰符public static final
构造方法 没有
成员方法 只能是抽象方法,存在默认的修饰符public abstract
类与类 , 类与接口, 接口和接口的关系
类与类: 继承关系(extends),只支持单继承,不支持多继承 , 但是可以多层继承
类与接口: 实现关系(implements) , 可以是单实现,也可以是多实现,并且一个类可以在继承一个类的同时,实现多个接口
接口和接口:
继承关系(extends),可以是单继承,也可以是多继承
抽象类和接口的区别:
a: 成员区别
抽象类
成员变量 可以是变量,也可以是常量
构造方法 有
成员方法 可以是抽象方法,也可以非抽象方法
接口
成员变量 只能是常量public static final
构造方法 没有
成员方法 只能是抽象方法public abstract
b: 关系区别
类与类: 继承关系(extends),只支持单继承,不支持多继承 , 但是可以多层继承
类与接口: 实现关系(implements) , 可以是单实现,也可以是多实现,并且一个类可以在继承一个类的同时,实现多个接口
接口和接口:
继承关系(extends),可以是单继承,也可以是多继承
c: 设计理念
抽象类 体现的是"is a"关系定义的都是该继承体系中共性的内容
接口 体现的是"like a"关系定义的都是该继承体系中扩展性的东西
一、面向对象思想:
面向过程:关注步骤和过程
面向对象:关注的是对象
面向对象是基于面向过程的
(1)类的定义
手机事物:属性:
品牌 , 颜色 , 价格 .....行为:
打电话 , 发短信 , 打游戏 ....手机类:成员变量:
品牌(brand) , 颜色(color) , 价格(price) 成员方法: 打电话(call) , 发短信(sendMessage) , 打游戏(playGame)
class Phone { // 成员变量 String brand = "三星"; // 品牌 String color = "白色"; // 颜色 int price = 1999 ; // 价格 // 成员方法 // 打电话(call) public void call(String name){ System.out.println("给" + name + "打电话"); } // 发短信(sendMessage) public void sendMessage(String name){ System.out.println("给" + name + "发短信"); } // 打游戏(playGame) public void playGame(){ System.out.println("玩游戏...."); } }
(2)类与对象
我们学习编程的目的? 为了模拟现实生活中的事物 .
如何描述现实生活中的事物呢?
学生:
姓名,年龄, 性别 ....
学习 , 吃饭 , 睡觉 ....
属性: 就是事物的描述信息
行为: 就是该事物可以做什么事情
而我们java语言的最小单位是一个类. 所以我们就找到了事物是java语言中的一个东西的对应关系.
事物类
属性 成员变量
行为 成员方法
成员变量: 和之前定义变量一样,只不过位置不同,在类中方法外
成员方法: 和之前定义方法一样,只不过去掉static(后面在讲解)
类: 是一组相关属性和行为的集合, 类是一个抽象的东西
对象: 就是该类的一个具体体现
举例:
学生 类
班长 对象
使用类:
创建对象: 格式:
类名 对象名 = new 类名();
访问成员变量的格式:
对象名.变量名 ;
访问成员方法的格式:
对象名.方法名(...)
创建对象的步骤:
Student s = new Student();
步骤:
(1): 加载Student的字节码文件到方法区
(2): 在栈内存中为s开辟空间
(3): 在堆内存中为new Student()开辟空间
(4): 给成员变量进行默认初始化
(5): 给成员变量进行显式初始化
(6): 通过构造方法对成员变量赋值
(7): 将堆内存中的地址值赋值给栈内存中的引用变量s
(3)一个对象的内存图
(4)局部变量和成员变量的区别:
a: 在类中的位置不同
局部变量: 在方法定义中或者方法声明上的变量
成员变量: 在类中方法外
b: 在内存中的位置不同
成员变量: 在堆内存
局部变量: 在栈内存
c: 生命周期不同
成员变量: 随着对象的创建而产生,随着对象的消失而消失
局部变量: 随着方法的调用而产生,随着方法的消失而消失
d: 初始化值的问题:
成员变量: 有默认值(系统给定)
局部变量: 没有默认值,必须对其赋值以后才能使用
变量的注意事项:
a: 局部变量可以和成员变量的名称一致
b: 变量在访问的时候,遵循一个原则"就近原则"
(5)java语言中的参数传递问题:
基本数据类型的参数传递,形式参数的改变对实际参数没有影响
引用数据类型的参数传递,形式参数的改变对实际参数是有直接影响的
引用数据类型: 数组 , 类 , 接口
如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
class Demo { public void show(int a){ System.out.println(a); } } class Student { public void method(){ System.out.println("student的method方法被调用了"); } } class StudentDemo { // 以后在看到某一个方法上,需要一个类类型的变量.那么我们在调用的时候,需要传递的是一个该类的对象 public void function(Student s){ // Student s = new Student(); s.method(); } } // 测试类 class ArgsDemo { public static void main(String[] args){ // 创建Demo对象 Demo d = new Demo(); // 调用方法 // int a = 20 ; d.show(20); System.out.println("----------------------------"); // 创建StudentDemo对象 StudentDemo sd = new StudentDemo(); // 创建Student对象 Student s = new Student(); sd.function(s); } }
(6)匿名对象: 就是没有名字的对象
匿名对象的作用:
a: 调用方法,仅仅调用一次的时候
b: 作为参数传递
class Student { public void show(){ System.out.println("student的show方法被调用了"); } } class StudentDemo { public void method(Student s){ s.show(); } } // 测试类 class NoNameDemo { public static void main(String[] args){ // 创建Student对象 Student s = new Student(); // 调用show方法 s.show(); // s.show(); System.out.println("---------------------------"); // 匿名对象 // new Student(); new Student().show(); // new Student().show(); 重新创建了一个对象和之前不一样 System.out.println("---------------------------"); // 创建StudentDemo对象 // StudentDemo sd = new StudentDemo(); // 调用method方法 // sd.method(s); // 把匿名对象作为参数传递 // sd.method(new Student()); new StudentDemo().method(new Student()); } }
二、面向对象的3个特征:
封装
继承
多态
面向对象开发
就是不断的创建对象,使用对象,指挥对象做事情。
(1)封装
我们在赋值的时候,发现有时候可以为负数.但是我们都知道年龄不能为负数.所以我们应该对数据做一个校验吧.
我们需要将校验放在Student类中还是PrivateDemo类中?应该放在Student类中.为什么呢?
PrivateDemo 是一个测试类,既然是测试类,那么我们就需要测试所有的数据,而不能将错误的数据进行过滤吧.
校验: 我们需要使用一个逻辑的判断.所以我们需要使用语句.语句只能写在方法中,所以我们需要在Student类中
编写一个方法.(作用: 是给age设置值)
我们在使用的时候,我们还可以通过成员变量直接对其赋值.这样不太友好.
我们需要其强制的使用方法来对age设置.言下之意,就是不能让外界直接访问成员变量age.
这时候java就给我们提供了一个关键字: private (私有的)
封装的思想:
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
封装好处
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性。
封装原则
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问
a、private关键字的特点:
a: private是一个修饰符
b: 可以用来修饰成员变量和成员方法
c: 被private修饰的成员只能在本类中访问
// 学生类 class Student { // 成员变量 String name ; // 姓名 private int age ; // 年龄 // 定义一个方法.作用: 是给age设置值 public void setAge(int a){ if(a > 120 || a < 0){ System.out.println("数据非法!!!"); }else { age = a ; } } // 成员方法 // 用来输出所有的成员变量 public void show(){ System.out.println(name); System.out.println(age); } } // 测试类型 class PrivateDemo { public static void main(String[] args){ // 创建对象 Student s = new Student(); // 给成员变量赋值 s.name = "凤姐"; // s.age = 38 ; s.setAge(38); // 调用show方法 s.show(); System.out.println("-------------------------"); // 创建学生对象 Student s2 = new Student(); // 给成员变量赋值 s2.name = "刘亦菲"; // s2.age = -27 ; s2.setAge(-27); // 调用show方法 s2.show(); }
b、this关键字:
我们在起名字的时候,要做到的"见名知意",但是现在没有做到"见名知意",所以我们需要更改一下下.
this关键字: 代表的是本类对象的一个引用, 谁调用我this就代表谁.
this的存在解决的问题: 当局部变量将成员变量隐藏的时候,我们就可以通过this来明确直接访问的是成员变量.
变量在访问的时候遵循一个就近原则,现在我们的局部变量的名称和成员变量的名称一致.
所以在赋值的时候,并没有涉及到成员变量.
而我们的目的是: 把传递进来的name赋值为成员变量的name
我们访问成员变量只能通过对象来进行访问,那么谁有可以代表当前类的一个对象呢?
这时候java就给我们提供了一个关键字: this
c、构造方法
特点:
(1): 方法名和类名相同
(2): 没有返回值类型,连void也没有
(3): 没有返回值
作用:
给成员变量赋值
注意事项:
(1): 当我们没有给出构造方法的时候,系统将会提供一个默认的无参的构造方法
(2): 当我们给出构造方法的时候,系统将不会提供一个默认的无参的构造方法
d、static关键字
特点:
(1): 随着类的加载而加载
(2): 优先于对象存在
(3): 被类的所有的对象所共享
(4): 可以通过类名调用.本身也可以通过对象名调用
建议使用类名调用
注意事项:
(1): 在静态的方法中不能存在this关键字
(2): 静态只能访问静态
e、代码块
概述: 在java中使用{}括起来的内容
分类: 局部代码块 , 构造代码块 , 静态代码块 , 同步代码块(多线程)
局部代码块:
位置在方法定义中
构造代码块: 位置在类中方法外 , 特点: 每创建一次对象都调用一次 , 并且优先于构造方法执行
静态代码块:
位置在类中方法外 , 前面添加一个static 特点: 随着类的加载而加载,只执行一次 ,优先于构造代码块
(2)继承
格式:class 子类名 extends 父类名 {}
好处:
(1): 提高了代码的复用性
(2): 提高了代码的维护性
(3): 让类与类产生了关系,是多态的前提
弊端:
让类与类产生了关系,增强了耦合性
特点:
(1): 只能是单继承 ,不能是多继承
(2): 可以使用多层继承
注意事项:
(1): 父类中私有的成员不能被子类继承
(2): 父类中的构造方法不能被子类继承,但是可以通过super去访问
(3): 不能为了部分功能去使用继承
继承中成员变量的访问特点:
变量在访问的时候遵循一个"就近原则"
查找顺序:
(1): 在子类的局部位置
(2): 在子类成员位置
(3): 在父类的成员位置找
(4): 报错
this和super的区别:
this: 表示是本类对象的一个引用,谁调用我this就代表谁
super:表示的是父类存储空间的一个标识(理解: 父类对象的运用)
成员访问格式:
成员变量
this.变量名
本类的成员变量
super.变量名
父类的成员变量
构造方法
this(...)
本类的构造方法
super(...)
父类的构造方法
成员方法
this.方法名(...) 本类的成员方法
super.方法名(...)父类的成员方法
继承中构造方法的访问特点:
子类在初始化的时候,默认去调用父类的无参的构造方法
所有的构造方法的第一句都是super()
注意事项:
this(...) 和 super(...)必须是构造方法第一行
Object:
所有的类都是直接的或者间接的继承自该类
继承中成员方法的访问特点:
查找顺序:
(1): 在子类中查找
(2): 在父类中查找
(3): 报错
方法重写与方法重载的区别
方法重写: 子类中出现了和父类中一模一样的方法(方法名, 返回值类型 , 参数列表)
方法重载: 在同一个类中,允许同时存在一个以上的同名方法只要它们的参数列表不同, 与返回值无关
final关键字
特点:
final(最终的)
修饰类 被修饰的类不能被继承
修饰变量 被修饰的变量其实是一个常量
引用类型 指的是地址值不能被改变
基本类型 指定是值不能被改变
修饰方法 被修饰的方法不能被子类重写
final的初始化时机问题:
a: 只能被赋值一次
b: 在构造方法结束前赋上值就OK了(非静态的)
// 动物 class Animal { // 成员变量 private String name ; private int age ; private String color ; // 构造方法 public Animal(){} public Animal(String name , int age , String color){ this.name = name ; this.age = age ; this.color = color ; } // 提供get和set方法 public void setName(String name){ this.name = name ; } public String getName(){ return name ; } public void setAge(int age){ this.age = age ; } public int getAge(){ return age ; } public void setColor(String color){ this.color = color ; } public String getColor(){ return color ; } // 成员方法: 吃饭 , 睡觉 public void eat(){ System.out.println("吃饭了...."); } public void sleep(){ System.out.println("睡觉"); } } // 猫 class Cat extends Animal { // 给出构造方法 public Cat(){} public Cat(String name , int age , String color){ super(name , age , color); } // 抓老鼠 public void catchMouse(){ System.out.println("哦,抓到了一只老鼠..."); } } // 狗 class Dog extends Animal{ // 给出构造方法 public Dog(){} public Dog(String name , int age , String color){ super(name , age , color); } // 看门 public void lookDoor(){ System.out.println("狗正在看门.."); } } // 测试类 class ExtendsTest3 { public static void main(String[] args) { // 创建一个狗对象 Dog d1 = new Dog(); // 给成员变量赋值 d1.setName("旺财"); d1.setAge(3); d1.setColor("黄色"); // 输出成员变量 System.out.println(d1.getName() + "----" + d1.getAge() + "---" + d1.getColor()); System.out.println("-------------------------------"); // 创建对象 Dog d2 = new Dog("哮天犬" ,45 , "黑色" ); // 输出成员变量 System.out.println(d2.getName() + "----" + d2.getAge() + "---" + d2.getColor()); System.out.println("-------------------------------"); d2.eat(); d2.sleep(); d2.lookDoor(); } }
(3)多态
前提:
(1): 需要有继承
(2): 需要有方法重写,没有方法重写也是可以的,但是没有意义
(3): 父类的引用指向子类对象
Fu f = new Zi();
多态中成员的访问特点:
成员变量: 编译看左边, 运行看左边
成员方法: 编译看左边 , 运行看右边
静态成员方法:
编译看左边 , 运行看左边
好处:
(1): 提供了代码的维护性(继承)
(2): 提供了代码的扩展性(多态)
弊端:
不能访问子类特有的功能
向下转型: 就是把父类的引用强制转换成子类的引用Zi zi = (Zi)f ;
向上转型: 父类的引用指向子类对象Fu f = new Zi();
抽象类
特点:
(1): 抽象类格式:
abstract class 类名 {}
抽象方法的格式:
public abstract 返回值类型 方法名(...);
(2): 抽象类中可以有非抽象方法,也可以有抽象方法,如果一个类中存在抽象方法,那么就需要将该类定义为抽象类
(3): 构造方法
有, 用于子类在访问数据的时候初始化
(4): 抽象类不能对其进行直接实例化,但是可以对其进行间接的实例化(多态的形式)
(5): 抽象类的子类
a: 可以是抽象类
b: 可以是具体的类,但是这个具体的类需要重写抽象类中的抽象方法
成员特点:
(1): 成员变量可以是变量,也可以是常量
(2): 构造方法有 , 用于子类在访问数据的时候初始化
(3): 成员方法可以是抽象方法,可以是非抽象方法
面试题:
abstract不能和那些关键字进行共存?
private冲突
final冲突
static无意义
接口
特点:
(1): 定义接口的格式
interface 接口名{}
(2): 类实现接口的格式
class 类名 implements 接口名{}
(3): 接口不能对其进行直接的实例化,但是可以通过多态的形式对其进行间接的实例化
(4): 接口的子类
a: 可以是抽象类
b: 可以是非抽象类,该类必须重写接口中的抽象方法
(5): 接口中没有构造方法,并且接口中的方法都是抽象方法
成员特点:
成员变量 只能常量,存在默认的修饰符public static final
构造方法 没有
成员方法 只能是抽象方法,存在默认的修饰符public abstract
类与类 , 类与接口, 接口和接口的关系
类与类: 继承关系(extends),只支持单继承,不支持多继承 , 但是可以多层继承
类与接口: 实现关系(implements) , 可以是单实现,也可以是多实现,并且一个类可以在继承一个类的同时,实现多个接口
接口和接口:
继承关系(extends),可以是单继承,也可以是多继承
抽象类和接口的区别:
a: 成员区别
抽象类
成员变量 可以是变量,也可以是常量
构造方法 有
成员方法 可以是抽象方法,也可以非抽象方法
接口
成员变量 只能是常量public static final
构造方法 没有
成员方法 只能是抽象方法public abstract
b: 关系区别
类与类: 继承关系(extends),只支持单继承,不支持多继承 , 但是可以多层继承
类与接口: 实现关系(implements) , 可以是单实现,也可以是多实现,并且一个类可以在继承一个类的同时,实现多个接口
接口和接口:
继承关系(extends),可以是单继承,也可以是多继承
c: 设计理念
抽象类 体现的是"is a"关系定义的都是该继承体系中共性的内容
接口 体现的是"like a"关系定义的都是该继承体系中扩展性的东西
相关文章推荐
- C#面试 笔试题 五
- C#面试 笔试题 四
- 程序员编程艺术:第十章、如何给10^7个数据量的磁盘文件排序
- C#面试 笔试题 三
- C#面试 笔试题 二
- 黑马程序员——Java语言基础:其他对象(System、Runtime、Date、Calendar、Math)
- C# 面试 笔试题
- 面试必须get的技能点
- 面试问题集锦
- 黑马程序员-继承、接口与多态
- 面试---内联函数和宏定义的区别
- 黑马程序员——集合:泛型和新特性
- 面试大全
- 9本书在Java程序员书籍
- 京东面试,问到我是否用过GridView,又回来脑补
- interview 01
- 面试---sizeof
- 美团二面被打击,遇到一个最基础的问题:Activity的生命周期,回来一番恶补,总结如下
- 程序员的10条建议
- [转]关于现代CPU,程序员应当更新的知识