一、封装
在面向对象设计方法中,封装(Encapsulation)是指一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法,即屏蔽内部实现的细节,仅仅对外提供共有的方法/接口。
封装可以被认为一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改哪些调用我们代码的程序片断。
适当的封装可以让程序更容易理解与维护,也加强了程序的安全性。
(一)实现封装的步骤
1.修改属性的课件性来限制对属性的访问(一般为private),例如:
public class Person{ private String name; private int age; }
这段代码中,将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
2.对每个值属性提供对外的公共访问,也就是创建一对赋值方法,用于对私有属性的访问,例如:
/* 文件名:Test.java */ public class Test{ private String name; private int age; public int getAge(){ return age; } public String getName(){ return name; } public int setAge(int age){ this.age = age; } public String setName(String name){ this.name = name; } }
采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
(二)实例
一个java封装类的例子
/* 文件名:Test.java */ public class Test{ private String name; private int age; public int getAge(){ return age; } public String getName(){ return name; } public void setAge(int newAge){ age = newAge; } public void setName(String newName){ name = newName; } }
以上实例中public方法是外部类访问该类成员变量的入口。
通常情况下,这些方法被称为getter和setter方法。
因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。
通过如下的例子说明Test类的变量怎样被访问:
/* 文件名:Run.java */ public class Run{ public static void main(String[] args) { Test test = new Test(); test.setName("leslie"); test.setAge(20); System.out.println("Name : " + test.getName() + " Age : " + test.getAge()); } }
代码编译如下
注:
1.若一个类把自己的成员变量暴露给外部的时候,那么该类就失去对该成员变量的管理权,别人可以任意的修改你的成员变量。
2.封装中经常使用@property(即setter和getter方法)
3.在类的延展中对类进行分装,即:
@interface NSObject()
@end
二、继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
(一)类的继承格式
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class 父类{ } class 子类 extends 父类{ }
(二)继承类型
Java 不支持多继承,但支持多重继承。
(三)继承的特性
1.子类拥有父类非private的属性、方法
2.子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
3.子类可以用自己的方式实现父类的方法
4.Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性
5.提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)
(四)继承的关键字
1.extends关键字
在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。
public class Animal{ private String name; private int id; public Animal(String myName, int myId){ //初始化属性值 } public void eat(); public void sleep(); } public class Pig extends Animal{ }
2.super与this关键字
super关键字:
super 表示使用它的类的父类。
(1).调用父类的构造方法;
super(); 或 super(参数列表);
注意:静态方法中不能使用 super 关键字。
(2).调用父类的方法(子类覆盖了父类的方法时);
super.方法名(参数列表);
如果是继承的方法,是没有必要使用 super 来调用,直接即可调用。
但如果子类覆盖或重写了父类的方法,则只有使用 super 才能在子类中调用父类中的被重写的方法。
this关键字:表示当前对象,即指向自己的引用
/* 文件名:KeyTest */ 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 KeyTest{ public static void main(String[] args) { Animal a = new Animal(); a.eat(); Dog d = new Dog(); d.eatTest(); } }
输出结果为
3.final关键字
final关键字声明类可以把类定义为不能继承的,即最终类;
或者用于修饰方法,该方法不能被子类重写。
声明类:
final class 类名 {//类体}
声明方法:
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
注:实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final。
三、多态
多态是指同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。
Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。
Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。
多态体现为父类引用变量可以指向子类对象。
(一)多态的优点
1.消除类型之间的耦合关系
2.可替换性
3.可扩充性
4.接口性
5.灵活性
6.简化性
(二)多态成员的特点
1.多态成员变量:编译运行看左边
Fu f = new Zi(); System.out.println(f.num); //f是Fu中的值,只能取到夫中的值
2.多态成员方法:编译看左边,运行看右边
Fu f = new Zi(); System.out.println(f.show()); //f的门面类型是Fu,但实际类型是Zi,所以调用的是重写后的方法。
(三)instanceof关键字
Java中,instanceof运算符的前一个操作符是一个引用变量,后一个操作数通常是一个类(可以是接口),用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是返回true,否则返回false。
作用:用来判断某个对象是否属于某种数据类型。
注意:返回类型是布尔型;instanceof 操作符的左右操作数必须有继承或实现关系
Fu f1 = new Zi(); Fu f2 = new Son(); System.out.println(f1 instanceof Zi); //true System.out.println(f2 instanceof Zi); //false
(四)多态的转型
多态的转型分为向上转型和向下转型两种。
1.向上转型:多态本身就是向上转型的过程
使用格式:父类类型 变量名=new 子类类型();
适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。
2.向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型。
适用格式:子类类型 变量名=(子类类型) 父类类型的变量;
适用场景:当要使用子类特有功能时。
(五)多态存在的三个必要条件
继承、重写、父类引用指向子类对象
比如:
Parent p = new Child();
当使用多态方法调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
/* 文件名:Test.java */ class People{ // 基本类作为父类,有一个基本方法 public void eat(){ System.out.println("吃饭"); } } class Stu extends People{ //声明子类,继承父类,但有自己的方法(父类方法重写),并且实例化后优先使用自己的方法 @Override public void eat(){ System.out.println("吃水煮肉片"); } public void study(){ System.out.println("好好学习"); } } class Teachers extends People{ @Override public void eat(){ System.out.println("吃樱桃"); } public void teach(){ System.out.println("认真授课"); } } public class Test{ public static void main(String[] args) { People p = new Stu(); //向上转型 p.eat(); //调用特有的方法 Stu s = (Stu) p; //向下转型 s.study(); } }
输出结果为: