java中封装,继承,多态,接口学习总结
### 一:封装
java中封装是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制。封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
***封装的优点***
1 良好的封装能够减少耦合。
2 类内部的结构可以自由修改。
3 可以对成员变量进行更精确的控制。
4 隐藏内部信息,实现细节。
***实现java封装的步骤***
1 修改属性的可见性,一般设置为private,只限制本类访问
```java
private String name;
private int num;
```
2 对每个值属性提供对外的公开方法(设置setter,getter访问器)
快捷键:alt+shift+s(选择Generate getters and setters)
```java
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;
}
```
### 二:继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
***为什么需要继承?***
减少代码冗余,将具有共同行为的代码提取出来,封装为父类,由子类继承父类,减少代码的臃肿,方便后期修改!
***继承的特性***
1 java中不支持多继承,但支持多重继承。
![图片选自菜鸟教程](https://img-blog.csdnimg.cn/20200412103746375.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NjA4OTA2Ng==,size_16,color_FFFFFF,t_70#pic_center)2 子类具有父类所有非private的属性,方法。
3 子类可以拥有自己的属性和方法,即子类对父类的拓展
4 子类可以用自己的方式实现父类的方法(即子类重写父类方法)
5 提高的类的耦合性(继承缺点:耦合性越高,代码的独立性越差。)
***继承的关键字***
java中是单继承,extends只能继承一个类
```java
class A extends B{}
```
**super和this关键字**
super:使用super关键字访问当前父类的成员,用来应用当前对象的父类
this:对当前对象的引用(指向自己)
例:
```java
public class Pet{
void run(){
System.out.println("pet is running");
};
}
public class Cat extends Pet{
void run(){
System.out.println("Cat is running");
}
void runTest(){
super.run();
this.run();
}
}
public class Test{
public static void main(String [] args){
Pet pet = new Pet();
pet.run();
Cat cat = new Cat();
cat.runTest();
}
}
```
输出结果为:
pet is running
pet is running
Cat is running
注意:final关键字修饰的类定义为最终类,不能被继承
***构造器***
子类不继承父类的构造器(构造方法或构造函数),只是调用(显示或者隐式)。若父类的构造器带有参数,子类必须显示的通过super关键字调用父类的构造器并带有合适的参数。
若父类的构造器没有带参数,则不需要显示的通过super关键字调用,系统会默认调用父类无参构造器。
例:(选自runoob.com)
```java
class SuperClass {
private int n;
SuperClass(){
System.out.println("SuperClass()");
}
SuperClass(int n) {
System.out.println("SuperClass(int n)");
this.n = n;
}
}
// SubClass 类继承
class SubClass extends SuperClass{
private int n;
SubClass(){ // 自动调用父类的无参数构造器
System.out.println("SubClass");
}
public SubClass(int n){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass(int n):"+n);
this.n = n;
}
}
// SubClass2 类继承
class SubClass2 extends SuperClass{
private int n;
SubClass2(){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass2");
}
public SubClass2(int n){ // 自动调用父类的无参数构造器
System.out.println("SubClass2(int n):"+n);
this.n = n;
}
}
public class TestSuperSub{
public static void main (String args[]){
System.out.println("------SubClass 类继承------");
SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(100);
System.out.println("------SubClass2 类继承------");
SubClass2 sc3 = new SubClass2();
SubClass2 sc4 = new SubClass2(200);
}
}
```
输出结果为:
------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200
### 三:多态
多态指同一行为具有多种表现形式或形态的能力,多态就是同一个接口,使用不同实例而执行不同的操作。同一个事件发生在不同对象上会有不同的执行方法。
***多态的优点***
1 消除类型之间的耦合关系
2 可替换性
3 可扩充性
4 接口性
5 灵活性
6 简化性
***多态存在的必要条件***
1 继承
2 重写
3 父类引用指向子类对象
例:
```java
Pet cat = new Cat();
```
当使用多态调用方法时,首先检查父类是否存在改方法,若不存在,则编译错误,若存在,则去调用子类中同名方法。
好处:可以使程序有良好的拓展,可以对所有类的对象进行通用处理。
例:(选自runoob.com)
```java
public class Test {
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
}
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();
}
}
}
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("看家");
}
}
```
运行结果:
吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠
***多态的实现方式:***
1 重写
2 接口
3 抽象类和抽象方法
### 四:接口
接口(interface),一个类通过继承接口的方式,从而实现接口内部的抽象方法。
注意:接口并不是类。类描述对象的属性和方法,接口中包含类要实现的方法。除非实现接口的类为抽象类,否则要实现接口中的所有方法。
接口无法被实例化,但可以被实现。一个实现接口的类,则必须实现接口中的所有抽象方法,否则定义此类为抽象类。
***接口与类相似点***
1 一个接口可以有多个方法。
2 接口保存文件为.java结尾,文件名使用接口名。
3 接口的字节码文件保存在.class中。
4 接口保存的字节码文件必须在与包名相同的目录中。
***接口与类的区别***
1 接口不能实例化对象
2 接口中没有构造方法
3 接口中的所有方法为抽象方法,所有变量为静态变量。
4 接口中的变量只能为 public final static
5 接口支持多继承
6 接口不是被类继承了,而是要被类实现
***接口需注意的特性***
1 接口中的每一个方法都是抽象的(abstract)为 public abstract(其他修饰符会编译报错)
2 接口中的变量均被指定为 public,static,final,(private会编译错误)
3 接口中的方法为抽象方法,不能在接口中实现,只能由实现接口的类来实现。
**抽象类与接口的区别**
1 抽象类中的方法可以有方法体,接口中的方法均为抽象方法,不能有方法体
2 抽象类的成员变量可以是任意类型的,接口中只能是 public static final
3 接口中不能有静态静态代码块和静态方法。(jdk1.8以后可以有静态代码快和方法体)
4 一个类只能继承一个抽象类,而一个类可以实现多个接口
***接口的声明***
使用interface关键字
例:
```java
public interface Pet{
// public static final成员变量
// 抽象方法
public void eat();
public abstract void run();
}
```
***接口的实现***
使用implements关键字(可以实现多个接口,使用","分隔)
例:
```java
public abstract class Door {
public abstract void open();
public abstract void close();
}
public interface DoorBell {
void takePictures();
}
public interface Lock {
public abstract void lockUp();
void openLock();
}
public class TheftprootDoor extends Door implements Lock,DoorBell {
@Override
public void lockUp() {
// TODO Auto-generated method stub
System.out.println("上锁");
}
@Override
public void openLock() {
// TODO Auto-generated method stub
System.out.println("开锁");
}
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("开门");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("关门");
}
@Override
public void takePictures() {
// TODO Auto-generated method stub
System.out.println("拍照了");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TheftprootDoor thef = new TheftprootDoor();
thef.close();
thef.lockUp();
thef.openLock();
thef.open();
thef.takePictures();
}
```
代码执行结果:
关门
上锁
开锁
开门
拍照了
**重写接口中的方法时需注意:**
1 类在实现接口中的方法时,不能抛出异常,只能在接口中,或者继承接口的抽象类中抛出异常。
2 类在重写方法时,保证相同额方法名,或者互相兼容的返回值类型。
3 如果实现接口的类为抽象类,则不需实现接口的方法。
**实现接口时,需注意:**
1 一个类可以实现多个接口(使用“,”分隔)
2 一个类只能继承一个类,但可以实现多个接口
3 一个接口可以继承另一个接口(与类继承想类似)
***接口的多继承***
java中,类不允许多继承,但接口可以实现多继承,使用extends关键字,用","分隔开
```java
public interface Cat extends Run,Eat,Swim{}
```
***标记接口***
没有任何方法的接口被称为标记接口。
标记接口的目的:
1 立一个公共的父接口
2 向一个类添加数据类型:
(整理于2020/4/12,有错误之处希望大家提出。)