学无先后,达者为师

网站首页 编程语言 正文

面向对象OOP基础理解

作者:m0_72954164 更新时间: 2022-07-26 编程语言

一、两种编程思想

面向过程编程(Procedure Oriented Programming 简称为POP

        是一种基本的编程思想,是将一件事情按流程逐步实现。这种思想强调事情完成的过程,分析步骤写出相应的代码。

        如猜拳游戏,每一个步骤都能按顺序用代码描述出来,逻辑清晰。但如果逻辑复杂,如象棋游戏,则无法使用POP的思想实现。

        C语言就是一门标志性的面向过程编程语言。

面向对象编程思想(Object Oriented Programming 简称OOP )

        是当前主流的编程思想,将解决问题的所有参与对象 创建出来,赋予对象对应的 行为 属性
让这些对象互相配合完成,实现最终效果。 这种思想致力于将计算机中的世界,描述的和现实中一致。

面向对象的三大特性(封装、继承、多态)

封装

使用 private 关键字对属性进行修饰,可以防止除自身类之外的地方对该属性进行访问。
这样可以保护关键属性,隐藏类内部的实现细节,再对外提供一组公开的 get/set 方法用于对该属性的赋值和读取。

继承

A 可以通过 extends 关键字继承类 B
语法: class A extends B。
A 称为 子类 、派生类、衍生类、 subClass。
B 称为 父类 、基类、超类、 superClass。
继承后,子类可以访问父类中非私有的属性和方法。
不同的子类中相同的代码,都可以定义在父类中,减少子类中的代码冗余。
如小孩类和老人类都有姓名、年龄等属性,都有吃、睡等方法,那么就可以定义一个人类,将这些属性和方法写在里面,让小孩类和老人类继承人类。

继承的特点

如果多个类之中有相同或类似的代码,可以将这些代码提出来定义在一个公共的类中,这个类就是
父类。再让那些类去继承这个父类,这样就能减少子类的重复代码。
子类对象可以直接访问父类中非私有的属性和方法。
子类可以对父类中的方法进行拓展或覆盖,这称为方法重写,重写后,子类对象再调用该方法时,
执行的是重写后的内容。
java 中是单继承,一个子类只能有一个父类,一个父类可以有多个子类。
java 中可以多重继承,类 A 可以继承类 B ,类 B 也可以继承类 C ,这时类 A 可以访问类 B 和类 C 中非私
有的成员。
任何类都是 Object 类的子类。
在创建子类对象时,先执行父类中相应的构造方法。

方法重写override

当子类继承父类后,可以对父类中非私有的方法进行拓展。
这个行为称为方法重写。
重写用于子类拓展父类的某个方法。

重写要求

方法名、参数列表、返回值必须和父类一致
访问权限不能比父类更严格 ( 访问修饰符的范围要么相同要么更大 )
不能抛出比父类更大的异常
方法重载 overload
一个类中 ,如果多个方法的 方法名相同 参数列表不同 ( 参数类型不同或参数数量不同 ) 时,这些方法称 为重载的方法。同名不同参
重载用于在一个类中,某个方法在不同的条件下,执行不同的内容。

重载要求

方法名相同
参数列表 ( 参数类型和数量 ) 不同

重载和重写相关面试题

说出重载和重写的异同
构造方法能重载吗?能重写吗?
构造方法能重载不能重写
构造方法执行时,一定创建对象吗?
不一定。创建子类时自动调用父类构造方法,不创建父类对象。

作业
简易的商品管理系统
添加商品
删除商品
修改商品
查看所有
购买商品
public class Father{ 
    public Father(){ 
        fun(); 
}
    public void fun(){System.out.println("父类中的普通方法");}
}
    
public class Son extends Father{ 
    public Son(){ 
         fun(); 
}

public void fun(){
 System.out.println("子类中的普通方法"); 
} }
public class Test{ 
public static void main(String[] args){ 
//1.创建父类对象,调用父类中的无参构造, 
//2.调用父类中的fun()方法 new Father(); 
//1.创建无参的子类对象,先调用父类中的无参构造, 
//2.父类中的无参构造调用子类重写后的fun()方法, 
//3.调用子类中的无参构造,调用重写后的fun()方法 new Son();
 } 
} 
//最终输出 
父类中的普通方法 
子类中的普通方法 
子类中的普通方法

多态

多态是面向对象语言的一种特性,通常在代码中用于:需要使用一个父类对象时,实际传递的是一个子 类对象,这时可以将子类对象当做父类 对象使用。这种特性称为 多态
在不使用多态特性的情况下,假如要调用计算图形面积的方法,参数为圆时,输出圆的面积,参数为正 方形时,输出正方形的面积。。。如果有新的图形出现,就要再重载这个计算面积的方法。
如果使用多态,就可以不用重载那些方法,只需要定义一个参数为所有图形的父类,调用该父类对象的 计算方法。具体计算方法交给子类重写。这样就免去了重载的过程,只定义一个参数为父类对象的方 法,实际传递子类对象,调用方法时执行的是子类重写后的内容。

实现多态特性的前提

必须在继承关系中
子类的对象保存在父类的变量中(也称为向上转型)
//Father类是Son类的父类 
//原本应该是Father类的对象保存到f中,但这里用子类对象也可以 
Father f = new Son();
子类通常会重写父类的方法

总结

在需要父类对象时,将子类对象当做父类对象使用。
这时父类对象调用的是子类重写后的方法,不能调用子类中父类没有的方法

多态案例--"花木兰替父从军"

Woman

package com.hqyj.test2; 
public class Woman extends Soldier { 
    public Woman(String name) { 
        super(name); }
        /** 定义化妆的方法 * */ 
    public void dressUp() { 
        System.out.println(getName() + "化妆打扮"); }
        /** 重写父类的方法 * */
    @Override public void war() { 
        System.out.println(getName() + "男扮女装上阵杀敌"); 
    } 
}
Soldier
package com.hqyj.test2; 
public class Soldier { 
    private String name; 
    public String getName() { 
        return name; 
    }
    public void setName(String name) { 
        this.name = name; 
    }
    public Soldier(String name) { 
        this.name = name; 
    }
    public void war() { 
        System.out.println(name+"上阵杀敌"); 
    } 
}
测试类
package com.hqyj.test2; 
/** 花木兰替父从军 ** */ 
public class Main { 
    public static void main(String[] args) { 
        //原本是直接创建对象,调用方法 
        /*Soldier father = new Soldier("花爸爸"); 
        *father.war();
        */ 
        //突发情况:不能创建父类对象了 
        //创建一个子类对象 
        // Woman hml = new Woman("花木兰"); 
        //将子类对象保存到父类变量中 
        // Soldier soldier =hml; 
        Soldier soldier=new Woman("花木兰"); 
        //这时调用的war()方法是子类重写后的方法 
        soldier.war(); 
        //这里无法调用子类中父类里没有的方法

抽象abstract

是一个修饰符,用于修饰方法或类。

抽象类的特点

抽象类不能实例化 ( 不能创建抽象类的对象 )。
抽象类中可以有抽象方法,也可以有普通方法、构造方法 ( 除抽象方法外和普通类一样 )。
抽象类的构造方法在创建其子类对象时自动执行,但不会创建抽象类的对象。
某个类如果继承了抽象类,那么这个类要么也是抽象类,否则就要重写抽象类中的所有抽象方法。
通常抽象类都需要子类继承后重写其中的抽象方法。

接口interface

java 中,数据类型分为原始类型和引用类型。
引用类型分为:数组、类和接口。所以接口是一种数据类型,类似于类。类使用 class 定义,接口使用

interface定义。

如果一个抽象类中的所有方法都是抽象方法,那么就可以将这个抽象类定义为接口。

定义接口

访问修饰符 interface 接口名 {
}

二、类和对象

Class

具有相同的属性和行为的对象的集合,称为 " 一类 " 类也可以称为模板
属性 :描述对象的特征,在程序中,通过 定义变量 的形式表现属性。
行为 :描述对象的动作,在程序中,通过 定义方法 的形式表现行为。

定义类
[ 修饰符 ] class 类名 {
// 属性 ( 变量 )
// 行为 ( 方法 )
}

对象Object

创建对象:
类名 对象名 =new 构造方法 ( 参数 );

类和对象的关系

对象是类的具体表现,类是对象的合集 ( 模板 )
如包饺子时的模具就是一个类,每次用模具包出来的饺子都是一个个对象。
先定义模板类,才能通过类创建出对象。

简述成员变量和局部变量的区别以及生命周期

成员变量定义在类中,有默认值

局部变量定义在方法中,没有默认值
成员变量的生命周期:随着类创建对象,成员变量初始化,该对象回收,成员变量销毁
局部变量的生命周期:随着方法调用,局部变量初始化,方法调用结束,局部变量销毁

三、方法

概念

方法可以理解为一段独立的代码,能完成一件事,可以被重复调用。方法可以减少重复的代码。

调用方法

1、通过:“.”调用

Random rd = new Random();

//通过对象调用方法

rd.nextInt();

2、通过类名调用

/*

*math类*/

public class Test2 {

public static void main(String[] args) {

//Math类的使用

//Math类是一个数学工具类,其中包含了很多数学相关常量和运算的方法

//Math类中的方法都是静态方法,调用时,直接通过类名调用

//求绝对值

int i = Math.abs(-5);

System.out.println(i);

//求最大最小值

System.out.println(Math.max(1, -5));

        }

}

 3、通过对象调用

Random rd = new Random();

int rdNum=rd.nextInt();

Scanner sc = new Scanner(System.in);

int inp=sc.nextInt();

 自定义方法

 其中返回值方法名参数列表是组成方法的三要素。

返回值可以是任意数据类型(原始类型/引用类型)

参数列表只需写参数类型和参数名,多个参数用逗号隔开

访问修饰符可以不写

方法的分类

无参数无返回值的方法

void fun1(){

System.out.println("hello");

}

有参数无返回值的方法

void fun2(String name){

System.out.println("你好"+name);

}

无参数有返回值的方法

int fun3(){

return 2002;

}

构造方法

概念

是一个特殊的方法,没有返回值,方法名和类名一致。每个类在定义时,都有一个默认隐藏的无参
数的。构造方法,在创建对象时自动调用,通常用于初始化成员变量。

特点

没有返回值 ( 没有返回值,并不是 void) ,方法名和类名必须相同。
每个类默认有一个无参数的构造方法,方法体中没有内容。
构造方法不能通过 . 操作符调用,在创建对象时自动调用,所以通常用于初始化成员变量。
如果自己写了有参的构造方法,默认无参的构造方法就会失效,如果想要使用无参的构造方法,需
要再写出来才能使用。
构造方法可以限制创建对象时的参数。
可以同时存在多个不同参数的构造方法,这称为构造方法的重载。

继承时的特点

如果父类中重载了构造方法,默认无参构造方法就会失效,同时子类也会报错。
这时需要在子类的某个构造方法中,再调用父类的那个重载的构造方法即可。

四、包package

通过包可以将 .java 源文件进行结构化管理,相当于 windows 中的文件夹。
不同的包中,可以保存相同名称的 .java 源文件。
某个类在某个包中时,会在该类的代码最上加上 package 包名 ;

五、thissuper

这两个关键字,都可以当做对象或构造方法使用。

this当做对象使用

用法: this. 属性或 this. 方法。
这时的 this ,表示当前类的对象。只能在方法中使用。
通常用于在方法中区分成员变量和参数。如封装时的 set 方法就用到了 this 区分

public class Person{ 
    private String name; 
    public void setName(String name){ 
    //这里的this,表示当前类Person的一个对象 
    //相当于Person p = new Person()后的p。 
    this.name=name; 
    } 
}

this当做构造方法使用

用法: this([ 实际参数 ]);
此时的 this() 表示,当前类的一个构造对应的构造方法。
必须要写在另一个构造方法的第一行才能使用。
public class Father{ 
//任何类都隐藏有这段代码 
    public Father(){ 
    } 
}
public class Son extends Father{ 
    //对于每个使用了extends关键字的类来说,都隐藏有这段代码 
    public Son(){ 
    //调用父类中无参数的构造方法 
    super(); 
    } 
}
//以上代码可以看出,在创建子类对象时,会自动执行父类的构造方法。

super当做对象使用

用法同 this ,但 super 表示父类的对象。
可以通过 super 访问父类对象中的非私有属性和方法

原文链接:https://blog.csdn.net/m0_72954164/article/details/125981754

栏目分类
最近更新