Java的三大特性学习笔记
三大特性
4.2.1、封装
封装实际上就是将类的状态信息(成员变量)隐藏在类的内部,不允许外部程序直接访问。
访问修饰符
private | package-private | protected | public | |
---|---|---|---|---|
类内部访问 | 💕 | 💕 | 💕 | 💕 |
同包其他类访问 | × | 💕 | 💕 | 💕 |
同包子类访问 | × | 💕 | 💕 | 💕 |
不同包子类访问 | × | × | 💕 | 💕 |
不同包非子类访问 | × | × | × | 💕 |
封装的好处
4.2.2、继承
什么是继承
-
继承本质就是扩展,子类扩展了父类的功能(更强大)
-
-
public class Animal { //动物类 private String name; private int id; private String kind; public Animal(String name, int id, String kind) { this.name = name; this.id = id; this.kind = kind; } public void eat(){ System.out.println(name+"正在吃食物"); } public void sleep(){ System.out.println(name+"正在睡大觉"); } public void introduction() { System.out.println("大家好!我是"+ id + "号" + name + ",我的种类是"+kind); } }
public class Tiger extends Animal { //构造函数 public Tiger(String name, int id, String kind) { super(name, id, kind); } }
为什么要继承
-
复用
-
里氏代换原则
-
白盒复用?黑盒复用? x
如何继承
- 公用的东西写在父类中
- 一个类不可以同时继承两个父类
- Java不支持多继承
继承的语法规则
[访问修饰符] class 子类名 extends 父类名{
子类成员变量
子类成员方法
}
public class Superclass{
public void methodA(){......}
}
public class Subclass extends SuperClass{
public void methodB(){...}
}
Java继承究竟继承了什么?
1.类的成员与继承
JLS中定义了什么是类的成员,这是一个前提,子类仅仅继承父类/父接口的成员。类体中可以声明类的成员,即域、内部类型、方法。[8.1.6]
类体中还可以包含实例初始化块[instance initializers]、静态初始化块[static initializers]和构造器声明。它们不是类的成员,因此谈不上继承问题。并通过例子说明构造器不被继承。类的成员包括继承于直接父类/父接口的成员和类体中声明的成员。这是递归的。
2、访问修饰符对继承的影响
3、域的隐藏: hidden域不被继承
父类F中的[静态或实例]域x将被子类的同名域x隐藏[Hiding],不论两个x的数据类型如何和静态与否。父类的同名域不被继承。在子类体中使用简单名时,相当于this.x 。这种隐藏不会造成父类域访问上的困难,静态域使用F.x或super.x访问,实例域通过super.x访问。[BTW:局部变量可以shadows域]
在子类体外,被隐藏的父类域仍然可以访问。
学生管理系统
功能
4.2.3、多态
什么是多态
java程序可以聪明的根据不同情况,调用方法名相同,但是实现不同的方法。
多态是同一个行为具有多个不同的表现形式或者形态的能力。
多态的优点
- 消除类型之间的耦合关系
- 可替代性
- 可扩充性
- 接口性
- 灵活性
- 简化性
存在的条件
- 继承
- 重写
- 父类引用指向子类对象
什么是重载
方法名相同,参数类型不同。java程序可以根据参数类型自动调用合理的实现。
外壳不变,核心重写
//
public Student(String sName, String sNum, int sAge, String sex, String address) {
this.sName = sName;
this.sNum = sNum;
this.sAge = sAge;
this.address = address;
this.sex = sex;
}
//
public Student() {}
//
public Student(String sName, String sNum, int sAge) {}
为什么要重载
-
因为他们的功能相同,实现细节各异。
-
当然可以是不同的方法名的,减轻程序员的处理负担,统一一类行为。
-
两同三不同
- 同一个类
- 方法名相同
- 参数的个数,类型,顺序不同
- 仅是参数名不同,不能构成重载
- 仅是返回类型不同,不能构成重载
重写
当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。
class Animal{
public void eat(){
System.out.println("我需要吃东西!!");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("我是小金毛,我要吃骨头!!");
}
}
public class TestDog{
public static void main(String args[]){
Animal animal = new Animal(); // Animal 对象
Animal dog = new Dog(); // Dog 对象
animal.move();// 执行 Animal 类的方法
dog.move();//执行 Dog 类的方法
}
}
重写和重载的区别
- 相同
- 多态的一种
- 同名方法,就有不同实现
- 语言能自动根据不同的环境,调用不同的实现。让程序员主要精力放在业务逻辑,不必在具体调用上费心。
- 区别
- 多态调用条件不同,重载根据参数,重写根据真实对象类型
- 实现的原理不同。
- 重载在编译过程中根据参数类型编程不同命方法(静态(编译时)多态)
- 重写是在运行时根据类型定位具体实现(动态(运行时)多态)
总结:
经过这几天的学习,逐渐理清楚自己写代码过程中的逻辑,在写代码之前会提前想好自己要干嘛,需要完成什么。 今天是自己第四次重构自己的代码,翻回去看自己前边写的代码,第四次比第三次好一些,第三次比第二次好一些,前边两次简直写的惨不忍睹,逻辑混乱,代码也写得乱七八糟的,自己看了都会堵心。每一次写代码之前,将整个逻辑关系理清楚,写代码过程中尽可能的将易复用的公共代码封装,减少负担。