📚博客主页:爱敲代码的小杨.
✨专栏:《Java SE语法》
❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️
文章目录
- 1. 封装
- 1.1 封装的概念
- 1.2 为什么封装
- 1.3 封装的实现步骤
- 2. 继承
- 2.1 继承的概念
- 2.2 继承的格式
- 2.3 为什么继承
- 2.4 继承类型
- 2.5 继承特性
- 2.6 super 与 this 关键字
- 2.7 final 关键字
- 3. 多态
- 3.1 多态的概念
- 3.2 多态的优点
- 3.3 多态存在的三个必要条件
- 3.4 instanceof 关键字
面向对象三大特性:封装、继承和多态。
1. 封装
1.1 封装的概念
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
1.2 为什么封装
封装的目的是保护数据的安全和完整性,同时隐藏数据的实现细节,提高代码的可维护性和可扩展性,具体有以下几个方面的好处:
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
1.3 封装的实现步骤
-
修改属性的可见性来限制属性的访问(用
private
来修饰),如:public class Test { private String name; private int age; }
这段代码中,将
name
和age
属性设置为私有的,只有在本类中被访问,其他类访问不了,就实现对信息的隐藏。 -
对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,例如:
public class Test { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
采用
this
关键字是为了解决实例变量和局部变量之间发生的同名的冲突。
2. 继承
2.1 继承的概念
继承是 java
面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
生活中的继承
兔子和羊属于食草动物,狮子和老虎属于食肉动物。
食草动物和食肉动物又是属于动物。
所有的继承需要符合的关系:is-a,父类更通用,子类更具体。
虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。
2.2 继承的格式
在 Java
中通过关键字 extends
来声明一个类是从另一个类继承而来的,一般格式如下:
class 父类 {
}
class 子类 extends 父类 {
}
2.3 为什么继承
接下来我们通过实例的说明这个需求。
开发动物类,其中动物分别为狗和猫,要求如下:
- 狗:属性(姓名,颜色),方法(吃,叫)
- 猫:属性(姓名,颜色),方法(吃,叫)
class Dog{
private String name;
private String color;
public void eat() {
System.out.println(this.name + "正在吃...");
}
public void cry() {
System.out.println(this.name + "正在叫...");
}
}
class Cat {
private String name;
private String color;
public void eat() {
System.out.println(this.name + "正在吃...");
}
public void cry() {
System.out.println(this.name + "正在叫...");
}
}
从这两段代码可以看出来,代码存在重复了,导致后果就是代码量大且臃肿,而且维护性不高(维护性主要是后期需要修改的时候,就需要修改很多的代码,容易出错),所以要从根本上解决这两段代码的问题,就需要继承,将两段代码中相同的部分提取出来组成 一个父类:
class Animal {
private String name;
private String color;
public Animal(String name, String color) {
this.name = name;
this.color = color;
}
public void eat() {
System.out.println(this.name + "正在吃...");
}
public void cry() {
System.out.println(this.name + "正在叫...");
}
}
这个Animal类就可以作为一个父类,然后狗类和猫类继承这个类之后,就具有父类当中的属性和方法,子类就不会存在重复的代码,维护性也提高,代码也更加简洁,提高代码的复用性(复用性主要是可以多次使用,不用再多次写同样的代码) 继承之后的代码:
- 狗类
class Dog extends Animal{
public Dog(String name , String color) {
super(name, color);
}
}
- 猫类
class Cat extends Animal {
public Cat(String name , String color) {
super(name, color);
}
}
2.4 继承类型
Java
中不支持多继承,但支持多重继承。
2.5 继承特性
- 子类拥有父类非
private
的属性、方法。 - 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
2.6 super 与 this 关键字
super
关键字:我们可以通过super
关键字来实现对父类成员的访问,用来引用当前对象的父类
this
关键字:指向自己的引用。
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
// 运行结果
//animal : eat
//dog : eat
//animal : eat
2.7 final 关键字
final
关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写;
- 声明类
final class 类名 {
// 类体
}
- 声明方法
访问限定符 final 返回值类型 方法名(){
// 方法体
}
注意:实例变量也可以被定义为final
,被定义为final
的变量不能被修改。被声明为final
的类的方法自动声明为final
,但是实例变量并不是final
。
3. 多态
3.1 多态的概念
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:
多态性是对象多种表现形式的体现。
同一个事件发生在不同的对象上会产生不同的结果。
3.2 多态的优点
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
3.3 多态存在的三个必要条件
-
继承
-
重写
重写:子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不能改变。即外壳不变,核心重写。
重写的好处:在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。
class Animal { public void eat() { System.out.println("正在吃..."); } } class Dog extends Animal { public void eat() { System.out.println("狗正在吃狗粮..."); } } class Bird extends Animal { public void eat() { System.out.println("鸟正在吃鸟粮..."); } } public class Test1 { public static void fun(Animal animal) { animal.eat(); } public static void main(String[] args) { Dog dog = new Dog(); fun(dog); Bird bird = new Bird(); fun(bird); } } // 运行结果 狗正在吃狗粮... 鸟正在吃鸟粮...
重写(覆盖)的规则:
- 方法名相同
- 参数列表相同【顺序、个数、类型】
- 返回值相同
-
父类引用指向子类对象
比如:
Animal dog = new Dog();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
以下是多态的例子:
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
// 测试类
public class Test {
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型: 子类对象 -> 父类对象
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型: 父类对象 -> 子类对象
c.work(); // 调用的是 Cat 的 work
}
}
// 运行结果
吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠
3.4 instanceof 关键字
Java中可以使用instanceof
关键字判断对象是否是某个类的实例,语法格式如下:
对象 instanceof 类
在上述格式中,如果对象是指定类的实例对象,则返回true
,否则返回false
。
class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(this.name + "正在吃...");
}
}
class Dog extends Animal {
public String color;
public Dog(String name, int age,String color) {
super(name,age);
this.color = color;
}
public void eat() {
System.out.println(this.name + "正在吃狗粮...");
}
public void barks() {
System.out.println(this.name + "正在旺旺叫...");
}
}
class Bird extends Animal {
public Bird(String name, int age) {
super(name, age);
}
public void eat() {
System.out.println(this.name + "正在吃鸟粮...");
}
public void fly() {
System.out.println(this.name + "正在飞...");
}
}
public class Test1 {
public static void main(String[] args) {
Animal animal1 = new Dog("旺财",10,"黄色");
if (animal1 instanceof Bird){ // 判断 dog对象是否是Bird类的实例 如果是则实例化对象,否则打印hell
Bird bird2 = (Bird)animal1;
bird2.fly();
}else {
System.out.println("hell");
}
}
}