面向对象程序设计
面向对象程序设计(Object-oriented programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。
面向对象的三大特点:
- 封装:隐藏细节,将不需要外部访问的数据进行隐藏处理。
- 继承:用于对对象结构进行设计,用于类的属性和方法进行复用。
- 多态:即多种形态,在程序中表现为同一类型可以使用不同的类型实例化。
1.封装:
通过 对象名.属性名 修改属性值,对属性进行封装:
- Step1:将属性私有化,使用 private 修饰属性;
- Step2:提供属性的getter,setter方法,在方法内部对数据进行控制,限制外部的访问。
方法的分类:
- 使用 static 修饰的方法称为类方法;
- 类中的普通方法称为实例方法;
- 构造方法:用于类的实例化,在类实例化时由JVM自动调用。
访问修饰符 类名(参数列表){ //构造方法体 }
JVM会为每一个类创建一个空参实现的构造方法,一旦自定义构造方法后,将会覆盖掉原本的空参空实现的构造。
重载:在一个类中,同一个方法实现不同的操作,即方法的重载。
重载主要用于实现方法名的复用:在同一个类中,使用相同的方法名,不同的参数列表加以区分。
2.继承:
面向对象的重要机制,指一个对象可以直接调用另一个对象的属性和方法,以达到扩展原有的代码,而不必对源代码重新编写的目的。
程序中的继承源自生活
继承的关系:
- 单继承模式;
- 被继承的类称为父类,父类具备子类的通有特性;
- 继承父类的类称为子类;
- 子类应该比父类更具体。
子类:
/**子类 */
public class Child extends Father{
public Child(String name){
super(name);
System.out.println("子类构造中");
}
/**子类自身的方法 */
public void typeFatherName(){
System.out.println("typeFatherName");
//通过super关键字访问父类的属性或者方法
System.out.println(super.getName());
}
/**子类中修改name的方法 */
public void changeName(String name){
setName(name);
}
}
父类:
/**父类 */
public class Father extends GrandFather{
int a;
protected int b;
private String name = "father";
public Father(){
System.out.println("父类构造中");
}
/**父类中的带参构造 */
public Father(String name){
this.name = name;
System.out.println("父类构造中");
}
public void methodFather(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
祖父类:
/**祖父类 */
public class GrandFather {
int b;
public GrandFather(){
System.out.println("祖父类构造中");
}
public void methodGrandFather(){
}
}
说明:
- 继承使用关键字 extends 实现,被继承的类称为父类、基类或超类,继承父类的类型称为子类,也成为派生类;
- 子类将继承父类的所有属性和方法,私有属性和方法同样会被子类继承,但是不能在子类中直接访问;
- 子类在实例化(初始化)时将先对父类实例化(初始化);
- 如果父类中只有一个带参构造,JVM无法自动调用父类的构造方法(JVM只会调用父类的无参构造),此时必须要手动调用父类的构造方法;
- super表示对父类实例对象的引用,该关键字只能在子类中访问;
- Java中的继承模式是单继承模式,表示一个子类只能继承一个父类,但Java可以通过多重继承的方式呈现多继承的效果;
- 手动调用父类的构造方法必须写在子类构造的第一位置;
- 子类继承父类,应该比父类更具体:
更多的属性
更多的方法
重写父类的方法(对父类的方法改进或改写)
重写的要求:
- 重写只能在子类(以及接口的实现类)中实现;
- 重写要求方法的返回值类型、方法名、参数列表必须和父类保持一致(“@Overeide”用于检测方法是否能称为一个重写方法);
- 重写方法的访问级别不能低于父类的访问级别。
继承的优点:
提高代码的复用性;
允许对原有的类进行扩展;
实现面向对象的多态机制。
注:
在面向对象设计中:
//将子类中的实例赋值给父类类型,称为装箱;
parent = child;
//将父类类型中存放的子类实例进行强转获取,称为拆箱;
child = (child)parent;
child.method();
3.多态:
同一个类型在不同的环境下可以变化成多种形态的对象,多态需要使用继承或接口来实现,其具体表现为:
父类 = 子类的实例化; 接口 = 实现类的实例;
接口:对对象实体的行为特征进行限定的命名,实现面向对象的多态性。
关键字:interface
GUI:图形用户接口 API:应用程序接口
实例:
/**USB接口*/
public interface USB {
/**属性默认使用public static fianl修饰 */
public static final String type = "USB3.0";
/**接口中的方法默认使用public abstract修饰 */
public abstract void start();
/**传输数据 */
public void transletData();
}
/**U盘类 实现USB提供的规范*/
public class UDisk implements USB{
/**通过重写方式,实现接口中的抽象方法*/
@Override
public void start() {
System.out.println("U盘接入USB接口开始启动");
}
@Override
public void transletData() {
System.out.println("U盘可以读取并传输数据");
}
}
/**相机*/
public class Camra implements USB{
@Override
public void start() {
System.out.println("相机接口USB接口,开始启动");
}
@Override
public void transletData() {
System.out.println("相机开始读取照片数据");
}
}
public class Test {
public static void main(String[] args) {
//创建一个U盘
UDisk udisk = new UDisk();
//将U盘插入USB接口
//接口可以实现面向对象的多态性
USB usb = udisk;
usb.start();
usb.transletData();
//创建一个相机
Camra camra = new Camra();
//将相机插入USB接口
usb = camra;
usb.start();
usb.transletData();
}
}
说明:
- 接口中的方法都为抽象方法,没有方法体,接口都是抽象的,不能实例化;
- 接口中的方法默认使用 public abstract 修饰,其属性为公共静态的常量,默认使用 public static final 修饰;
- 接口的实现(关键字):implements;
- 实现接口必须要实现接口中定义好的方法(遵循接口的规范);
- 通过重写的方式,实现接口中的抽象方法;
- 一个类可以同时实现多个接口,必须要实现每个接口中的抽象方法,使用时必须要继承父类,后实现接口;
- 接口可以继承(相互继承),子接口的实现需要同时实现子接口与父接口的抽象方法。
抽象类:
/**抽象类 */
public abstract class MyAbstractClass {
/**抽象类中可以定义实例方法*/
public void method(){
System.out.println("method方法·");
}
/**抽象类中也可以定义抽象方法 */
public abstract void mehtod(int i);
}
public class ChildAbstractClass extends MyAbstractClass{
@Override
public void mehtod(int i) {
}
}
import java.util.Calendar;
public class Test {
public static void main(String[] args) {
//使用抽象类实现多态性,用来接受抽象类子类的实例对象
MyAbstractClass myClass = new ChildAbstractClass();
Calendar cal = Calendar.getInstance();
System.out.println(cal.getClass());
}
}
说明:
- 抽象类兼备了实例类和接口的特征,不能实例化;
- 抽象类中可以定义实例方法,也可以定义抽象方法;
- 抽象类使用继承 extends 实现,继承抽象类必须要实现抽象类中的抽象方法。
附:观察者模式的设计:
面向接口编程:抽象工厂模式的设计。
匿名类:在使用中同时创建实例对象。
内部类:内部类属于当前类的一部分,但在编译后将独立生成字节码文件。
import javax.swing.JOptionPane;
/**观察者模式的设计*/
public class User {
private ClickListener listener;
public User(){
}
/** 绑定监听器 */
public void bindClickListener(ClickListener listener){
this.listener = listener;
}
/** 用户的单击动作,单击动作需要实现的代码应该交给开发人员自定义实现*/
public void click(){
if(listener != null){
listener.clickMe();
}
}
public static void main(String[] args) {
User user = new User();
//通过监听器扩展User类Click方法的功能
user.bindClickListener(new MyListener());
user.click();
}
}