目录:
面向对象的三大特征:封装、继承、多态
包
方法重写
super
instanceof
面向对象的三大特征:封装、继承、多态
封装
— 合理隐藏(private)
— 合理暴露(protected、public)
隐藏不想被外界操作的field、方法、构造器
暴露一般就是希望给别人调用的方法。
封装的目的:A。简化编程
B。能更好的保证对象的完整性
为了实现隐藏,我们有 4 个修饰符
private — 当前类访问权限
没有访问权限修饰符 — 包访问权限
protected — 子类访问权限
public — 公共访问权限
private → 默认访问权限 → protected → public
private — 专门用于隐藏field
public — 专门用于暴露方法
protected — protected 修饰的方法,通常是希望被它子类访问
默认 — 希望在同一个包中被访问的成分
java访问权限修饰符局部变量 — 它仅在方法内有效,甚至仅在代码块内有效
它的作用域本身就小的可怜。连方法都出不了
所以它用访问权限修饰符,都是多余
继承
继承表达的是一种 “是(is a)”的关系,组合表达的是一种“有(has a)”的关系。
Java的继承 — 一个类与另一个类的关系
extends - 扩展
“is a”
类与类之间的关系:从 “一般到特殊” 的关系
人 → 老师 → IT老师 → Java老师
父类(基类、超类) → 子类
现实的继承 — 一个实例与另一个实例的关系。
“捞钱”
Java 的继承是 单继承,extends 后只有一个父类。
子类继承了父类,就可以获得父类的 Field 和方法。
如果你定义的Java类没有显式指定父类,系统会默认让它继承 Object 类
“一切类,都是Object类的子类”
方法重载(Overload):两同(同一个类,方法名相同),一个不同(形参)
方法重写(Override,也叫覆盖):两同、两小、一大
两同:方法名,形参列表相同
两小:子类重写的方法的返回值类型必须比父类方法的返回值类型更小,或相等
子类重写的方法的声明抛出的异常必须比父类方法声明抛出的异常更小,或相等
一大:子类重写的方法的访问权限必须比父类方法的访问权限更大,或相等
@Override // @Override 是让编译器执行更严格的检查,要求被修饰的方法,必须是重写父类的方法
super
— super 限定:强制去父类的方法
— super调用:用于显式调用父类的构造器
规则:子类的构造器【总会】调用父类的构造器【一次】
默认的情况下,子类构造器会自动调用父类无参数的构造器
如果希望明确指定子类构造器调用父类的哪个构造器,可用super (参数)来调用
super 调用必须出现在构造器第一行
super调用和this 调用都必须出现在构造器的第一行。
super调用和this 调用不能 同时出现
注意:
1. 如果既没有super调用,也没有this 调用
子类构造器会自动先调用父类无参数的构造器
2.如果有super调用
子类构造器会根据super 调用传入的参数去调用父类对应的构造器
3.如果有this 调用
子类构造器A会先找this 调用所对应类中被重载的构造器B。
多态(Ploymorphism)
由于有如下所示关系:
父类到子类的关系: 从一般到特殊的关系。
Animal a = new Wolf();
A. 第一个结论:【子类的实例,完全可以当作父类对象使用】
父类的引用变量,完全可以指向子类的实例。
多态: 同一个类型的变量,在执行同一个方法时,表现出多种行为特征
态 — 行为
多态增加了Java语言的灵活性,也是和设计模式紧密相连的。
Java 的引用变量有两个类型:
编译时类型:由声明它的类型来决定
运行时类型:由该引用变量实际所指向的对象来决定。
当我们【调用】引用变量时,它总是呈现出它的【运行时类型】的行为特征。
在编译阶段,编译器并不知道引用变量实际所引用的对象的类型
编译器只知道它的编译时类型
强制类型转换的运算符是(类型)
1.基本类型之间(除了boolean 之外),都可以进行转换
2.引用类型之间,只能在具有继承关系的两个类型之间转换
多态 (包含强制类型转换) 程序 及 运行结果:
class Person
{
public void work()
{
System.out.println("辛勤工作");
}
}
class Farmer extends Person
{
@Override
public void work()
{
System.out.println("锄禾日当午");
}
}
class Gongpu extends Person
{
@Override
public void work()
{
System.out.println("drinking");
}
public void drink()
{
System.out.println("我要玩游戏");
System.out.println("想多了,好好学习");
}
}
public class 多态
{
public static void main(String[] args)
{
/*
多态:同一个类型多个变量,在执行同一个方法时,
呈现出多种行为特征 — 这就是多态。
*/
Person p1 = new Person();
p1.work();
// 子类的实例,完全可以当作父类对象使用
Person p2 = new Farmer();
p2.work();
// 子类的实例,完全可以当作父类对象使用
Person p3 = new Gongpu();
p3.work();
// 编译阶段,编译器只知道它的编译时类型是Person
// 而Person类没有drink方法,所以下面代码是错的
// p3.drink(); // 在编译阶段,编译器认为p3是Person类型,而非Gongpu
// 强制类型转换
// gp和p3指向同一个对象,但gp 的编译时类型变成了Gongpu
Gongpu gp = (Gongpu)p3;
gp.drink();
}
}
多态Classcast (类型转换) 程序 及 运行结果:
public class Classcast
{
public static void main(String[] args)
{
// "向上转型"
Object ob = "Java";
/*
1. Object与System之间有继承关系,所以可以通过编译
2. 由于ob运行时类型是String,不是System
所以强转会引发ClassCastException
*/
System sys = (System)ob;
}
}
Classcastinstanceof
判断前面的变量所引用的对象,是否为后面类型的实例。是返回true,否返回false
注意点:instanceof 前面操作数的类型要么与后面的类相同,要么与后面的类有父子继承关系,否则会引起编译错误。
InstanceofTest 程序 及 运行结果:
public class InstanceofTest
{
public static void main(String[] args)
{
Object obj = "Hi";
// obj 的编译时类型(Object) 与 String有继承关系
// 因此代码可以通过编译
// 运行时返回true
System.out.println(obj instanceof String);
Object ob = new Integer(20);
// ob 的编译时类型(Object) 与 String有继承关系
// 因此代码可以通过编译
// 但运行时返回false
System.out.println(ob instanceof String);
Integer in = new Integer(30);
// ob 的编译时类型(Integer) 与 String没有继承关系
// 因此代码编译就报错。
System/out.println(in instanceof String);
}
}
InstanceofTestTest (到底输出哪个count,取决于该引用的变量的声明时的类型) 程序 及 运行结果:
class A
{
int count = 20;
}
class B extends A
{
// 子类的count Field 并不会覆盖父类的count。
int count = 200;
}
public class Test
{
public static void main(String[] args)
{
A a = new A();
System.out.println(a.count);
B b = new B();
// b所引用的对象有2 个 count Field
// 到底输出哪个count,取决于该引用的变量的声明时的类型
System.out.println(b.count);
// 这是典型的“向上转型”
A ab = b;
// == 用于判断两个引用变量是否指定同一个实例
// ab所引用的对象有2 个 count
// 到底输出哪个count,取决于该引用的变量的声明时的类型
System.out.println(ab == b);
System.out.println(ab.count);
}
}
内存图
包
包的作用就是“命名空间”的作用。
世界很大,公司很多,不同公司定义的类完全有可能出现同名的情况。
Java 要求,一个类的完整类名,必须是 “包名 + 类名”。
定义包的语法:
package 包1.包2.包. 包N;
包名的规则:
一般就是你公司的域名的倒写
—— 由于公司域名都是不可重复的,这样就保证不同公司的类的包名不会重复。
要把一个类放入包中,有两个要求:
A. 在该类的源代码中使用package 来声明包
B. 生成的class 文件必须放在相应文件结构下
一旦你为类定义了包后,该类的完整类名,包名 + 类名
当我们使用一个类时,包名 + 类名
为了减少每次都写包名的繁琐,Java 允许使用 import 来导入包下的类
Eg: import org.java.test.*; // 此处的*只能代表该包下所有类
普通的 import 是省略包
JDK 1.5提供的静态导入
import static — 导入指定类下的静态成员
从而允许省略类。
******************补充:********************
javac 的 -d 选项:
可以保证把生成 class 文件放到package 所对应的文件结构下
***************补充:*********************
目前遇到的三个异常:
1. NullPointerException —— 空指针
2.ArrayIndexOutOfBoundsException —— 数组越界
3.ClassCastException —— 类型转换异常
以上~未完
写在最后:
当初自己买耳机是为了听歌,但是买了之后突然发现就没怎么听了,定一个小目标,每天吃完午饭躺在椅子上认真的听一首歌,什么都不干,声音开大,闭着眼。暂且就叫做【每天一首歌】吧
【每天一首歌】【结婚-李志】
朋友圈看到一个小学同学发的,就点开来听,整个曲风有点凄凉。“只不过是一场生活,只不过是一场命运,只不过是一场游戏”。不太适合现在的我听~觉得歌曲中传达的是一个比较无奈的婚姻,对于我自己的爱情观来说,我不太可能会陷入这种场景,虽然见过很多文章说过,结婚了以后就会由爱情转换为亲情,那么随之而来的就不是爱情里的激情了,就变成了生活,会让你变得乏味,会消磨了你的激情,是柴米油盐酱醋茶~但是我不是很认同,我觉得结婚就是为了给伟大的爱情一个美好的结果,不要说我年轻不知愁滋味,这是一种态度,不管爱情也罢,婚姻也罢,都是要用心来呵护的,要两个人一起来运营。好看的皮囊很多,但是有趣的、合得来的灵魂真的可遇不可求~
愿看到本文的你和我都会有个好的结果~
下午看到初中那群兄弟在聊聚会,周末一起嗨,当然我回不去了,突然脑海里冒出一个词:初心。又不禁想起来自己的初心,竟然惊悚的发现我其实并没有一个明确的初心,我不知道初心和人生目标有没有交集。回到最初,我想做一个有价值的人,可是,衡量价值的标准在哪里,这很大很空,没有实际意义,慢慢的,我觉得自己挺想成为别人眼中的那种:有思想,积极向上,可以用精神思想来感染别人的人,好吧,我承认这样能装逼~算了,我还是想先变得有钱吧。所谓稀缺,缺少什么在意什么吧,太在意反而得不偿失,心境还是有待提升。像三傻大闹宝莱坞里男一,许是我的毕生所求吧,有着自己热爱的事业,事业可以得到认同,可以帮助别人,有着好兄弟,有着相爱的女人~
好了,双手脱离键盘,健身去了~
网友评论