网站首页 > java教程 正文
java中面向对象的三大特性:封装、继承、多态
封装
把抽象的数据和对数据的操作封装在一起, 隐藏变量的实现细节 。数据被保护在内部,程序的其他部分只有通过被授权的操作(成员方法)才能对数据进行访问。
1、原则
将不需要对外提供的内容都隐藏起来
把属性都隐藏,提供公共方法对其访问
2、好处
将变化隔离
便于使用
提高重用性
提高安全性
class FengZhuang{
private int age = 15;
public void setAge(int age) {
if (age > 0) {
this.age = age;
}
}
public int getAge() {
return this.age;
}
}
继承
java支持单继承,不直接支持多继承。
因为如果支持多继承,会产生调用的不确定性。(当继承的两个父类含有相同名字的方法时,不确定调用哪个。
继承可以解决代码复用的问题 ,当多个类存在相同的属性和方法时,我们可以从这些类中抽取出父类,在父类中定义这些属性和方法,只需要通过extends语句来声明继承父类。
父类的哪些属性可以被子类继承:
public
protected
默认修饰符
private( 只是继承后,相应的变量仍是私有的,不能直接访问 )
1、 子父类成员属性的特点
package 继承;
public class Test1 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.num = 3;//zi对象中没有自己写num属性,这个num属性是从父类中继承过来的
zi.show();
Zii zii = new Zii();
zii.show(); //奇怪,zi.num = 3 不是改变了父类中的num的值嘛?zii.show中的num不也应该等于3嘛?可是为什么等于2.可以知道成员继承只是实现了代码的复用,而不是内存的复用
}
}
class Fu{
int num1 = 1;
int num = 2;
}
class Zi extends Fu{
int num2 = 4;
public void show() {
System.out.println(num + "..." + num);//3...3
System.out.println(this.num + "..." + super.num);//3...3
System.out.println(num2 + "..." + num1);//4...1
}
}
class Zii extends Fu{
public void show() {
System.out.println(this.num + "..." + super.num);//2...2
}
}
从上面的例子看成员变量的内存分析图。
2、 子父类成员方法的特点
public class Test2 {
public static void main(String[] args) {
Demo1 d = new Demo1();
d.show();
}
}
class Demo{
String name;
public void show() {
System.out.println("fu show run");
}
public Demo() {
}
public Demo(String name) {//构造方法的重载
this.name = name;
}
}
class Demo1 extends Demo{
public void show() {//父类方法的重写
System.out.println("zi show run");
}
}
函数的两个特性
1、重载(同一个类中)
方法名可以相同
方法的参数类型、个数、顺序至少有一项不同
方法返回值类型可以不同
方法的修饰符可以不同
仅仅只是返回类型或修饰符不一样,不能构成重载
2、重写(子父类中)
子类的方法的返回类型、参数、方法名、要和父类的完全一致(也就是说修饰符可以不一致,请看第二条),否则就不构成重写
子类方法不能缩小父类方法的访问权限(即修饰符问题)
什么时候使用重写:当对一个类进行子类的扩展时,子类需要保留父类的功能声明。但是要定义子类中该功能特有的内容时,可以使用重写。
3、 子父类构造函数的特点
public class TestSuper2 {
public static void main(String[] args) {
System.out.println("开始创建一个ChildClass对象");
new ChildClass1();
}
}
class FatherClass1 {
int m = 12;
static {
System.out.println("hello");
}
public FatherClass1() {
System.out.println(m);
System.out.println("创建FatherClass");
show();
}
public void show() {
System.out.println("Father show");
}
}
class ChildClass1 extends FatherClass1 {
int num = 15;
static {
System.out.println("hello1");
}
public void show() {
System.out.println("Child show..." + num);
}
public ChildClass1() {
super();
//super执行完后,才对子类ChildClass1进行成员变量的显示初始化
System.out.println(num);
System.out.println("创建ChildClass");
}
}
直接看运行结果,我们再来分析。在分析之前,我们先明确一个概念: 构造函数用于对象的初始化,而静态初始化块用于类的初始化 。
开始创建一个ChildClass对象
hello
hello1
创建FatherClass
Child show...0
创建ChildClass
分析:
程序首先从main方法入手,先打印出“开始创建一个ChildClass对象”。之后创建一个ChildClass1的实例。
在实例化之前,先进行类加载。先沿着继承树上溯到Object类。先执行Object类的静态初始化块,在向下执行子类的静态初始化块,直到我们实例化类的静态初始化块为止。类的初始化过程只进行一次。(即先进行类加载,类加载过程只进行一次)。这就是为什么会先后打印出hello和hello1。
在堆内存中开辟空间,分配地址。并在对象空间中,对对象中的成员变量进行默认初始化。
调用构造函数,进行特定数据的初始化(即this.name = name等)。这里要注意: 在调用构造函数前已经完成成员变量的默认初始化。
进入构造函数时,第一行会先调用父类的构造函数进行父类初始化。(调用父类的构造函数前,也已经完成了父类的默认初始化)。先后打印出:12,创建FatherClass,Child
show…0。
父类的super()函数执行完毕后,执行栈返回子类的构造函数,再对子类的成员变量进行显示的初始化。(此时输出15)
最后进行的是对特定数据的初始化。即this.name = name等。
需要注意的是: 成员变量的默认初始化是在调用构造函数之前,而显示初始化是在进入构造函数调用父类的super()方法之后。特定数据的初始化则在最后进行。
多态
1、 成员属性的特点
package 多态;
public class chengyuanshuxing {
public static void main(String[] args) {
Fu zi = new Zi();
System.out.println(zi.num);//4
}
}
class Fu{
int num = 4;
}
class Zi extends Fu{
int num = 5;
}
多态时,成员属性的特点:
编译时,参考父类型上是否有调用的成员属性,有则编译通过,没有则编译失败。
运行时,参考父类型中是否有该成员属性,运行该成员属性。
简单说编译和运行都参考左边
2、成员函数的特点
package 多态;
public class chengyuanshuxing {
public static void main(String[] args) {
Fu zi = new Zi();
zi.show();//"zi show"
}
}
class Fu{
void show() {
System.out.println("fu show");
}
}
class Zi extends Fu{
void show() {
System.out.println("zi show");
}
}
多态时,成员函数的特点:
编译时,参考父类型上是否有调用的成员方法,有则编译通过,没有则编译失败。
运行时,参考的是对象所属的类中是否有该成员方法,运行该成员方法。
简单说编译看左边,运行看右边
虽然类型是父类型,但是运行时this指向的是当前new实例的引用。
3、静态方法的特点
package 多态;
public class chengyuanshuxing {
public static void main(String[] args) {
Fu zi = new Zi();
zi.show();//"zi show"
}
}
class Fu{
void show() {
System.out.println("fu show");
}
}
class Zi extends Fu{
void show() {
System.out.println("zi show");
}
}
多态时,静态方法的特点:
编译时,参考父类型上是否有调用的静态变量,有则编译通过,没有则编译失败。
运行时,参考父类型中是否有该静态变量,运行该静态变量。
简单说编译和运行都参考左边
静态方法是基于类的,而多态是基于对象的 ,所以调用时,该对象是那个类型的就调用相应类的静态方法。且 静态方法不具有多态性
写在最后:欢迎留言讨论,欢迎关注小编!
猜你喜欢
- 2024-10-21 从零学java笔录-第39篇 基础第二阶段 1 面向对象思想及概述
- 2024-10-21 C/C++编程笔记:C++面向对象和Java面向对象的区别
- 2024-10-21 面向对象—java中类与对象#java基础
- 2024-10-21 Java面向对象特征(java的面向对象特征)
- 2024-10-21 Java基础语法之面向对象(java中的面向对象)
- 2024-10-21 Java面向对象概念解析(java面向对象的意思)
- 2024-10-21 java中的面向对象总结(java中的面向对象总结法是什么)
- 2024-10-21 java面向对象总结(java面向对象知识点总结)
- 2024-10-21 Java基础:Java面向对象的特征(java面向对象的主要特征)
- 2024-10-21 好程序员Java培训分享Java面向对象概念解析
你 发表评论:
欢迎- 07-21如何将 iPhone 中的联系人导出到 Excel/CSV?
- 07-21sql查询的字段数据中有逗号。放到csv文件会分开,如何解决?
- 07-21在 WebAPI 里生成 csv zip 文件(webapi怎么发布在iis上)
- 07-21如何把csv格式转换成Excel格式(csv格式怎么转换)
- 07-21如何将高程导出为XYZ或CSV高程点(如何将高程数据导入cad)
- 07-21使用python把csv汇总成excel(python怎么将csv文件中的列存入列表)
- 07-21解决PHP导出CSV文件中文乱码问题(php导出excel文件)
- 07-21使用vba将Excel 文件转成 CSV 文件
- 最近发表
-
- 如何将 iPhone 中的联系人导出到 Excel/CSV?
- sql查询的字段数据中有逗号。放到csv文件会分开,如何解决?
- 在 WebAPI 里生成 csv zip 文件(webapi怎么发布在iis上)
- 如何把csv格式转换成Excel格式(csv格式怎么转换)
- 如何将高程导出为XYZ或CSV高程点(如何将高程数据导入cad)
- 使用python把csv汇总成excel(python怎么将csv文件中的列存入列表)
- 解决PHP导出CSV文件中文乱码问题(php导出excel文件)
- 使用vba将Excel 文件转成 CSV 文件
- python爬虫25 | 爬取的数据怎么保存?CSV了解一下
- MySQL 导出数据(mysql 导出数据 判断成功)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)