JAVA基础第一部分-面向对象

本文详细介绍了Java中的面向对象编程概念,包括对象、封装、继承和多态。封装通过访问控制级别保护数据,继承允许类的扩展,多态则实现了接口的重用。文章还提到了抽象类和接口的区别,并给出了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

一、面向对象与面向过程

JAVA是一种纯面向对象程序设计(OOP)语言,程序中所有相关的程序运算或执行操作,都是利用由类产生的对象来控制
那什么是面向对象编程?和面向对象编程不同的,是面向过程编程。

①、什么是面向过程?

面向过程:
就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
举例:大象装进冰箱需要几步?
在这里插入图片描述
按照面向过程思想:
第一步:工作人员去打开冰箱门
第二步:把大象塞进冰箱
第三步:工作人员把冰箱门关上
诶,这里我们就看出来了,面向过程就是把一件事按步骤一步一步来实现
面向过程编程,是把模型分解成一步一步的过程。

②、什么是面向对象?

对象,就是对问题中的事物的抽象
面向对象:
就是把现实中的事物都抽象为“对象”。每个对象是唯一的,且都可以拥有它的属性与行为。我们就可以通过调用这些对象的方法、属性去解决问题。
冰箱作为一个对象;
大象作为一个对象。
冰箱有这些功能:开门、装物体、关门
面向对象的好处,就包括有很好的延展性,比如我给大象赋予了一个吃的功能,它通过调用就可以在冰箱里去吃东西。面向对象就是把现实问题抽象为对象,通过调用每个对象的属性或功能去解决问题。

二、面向对象

2.1. 什么是 Object(对象)

Object(对象)相当于中文语义“东西”。
Object 是指一个具体事物实例,比如飞机、狗、运气、哲学等看得见的,看不见得,有形的、无形的,具体的,抽象的都是对象,总之“一切皆 Object”。

2.2. 面向对象

面向对象(Object Oriented),是指面向客观事物之间的关系。人类日常的思维方式是面向对象的,自然界事物之间的关系是对象和对象之间的关系
面向对象的定义:
首先 根据客户需求抽象出业务对象
然后 对需求进行合理分层,构建相对独立的业务模块
之后 设计业务逻辑,利用多态、继承、封装、抽象的编程思想,实现业务需求;
最后 通过整合各模块,达到高内聚、低耦合的效果,从而满足客户要求。

2.3. 面向对象概念

  • 类型(类):一个名词概念,如:客人、菜品、厨师
  • 引用(变量):指引用具体概念实例的代词,如:某人、特价菜
  • 对象(东西):指具体概念的个体实例,如:张三丰、一盘大盘鸡如上三者之间的关系可以体现为:“今天的特价菜是一盘大盘鸡,张三丰吃了”
  • 行为:方法 eat() sleep()
  • 多态:行为或引用,在具体情形下会发生变化的现象
    比如:“一只动物”可以是“一匹马”、“一头驴”、“一只猴子”,多态的; “打”可以是“打酱油”、“打麻将”,“打人”,根据宾语发生变化多态的。
  • 封装:任何对象实例都是尽可能封装, 减少暴露,它的实现细节对你是透明的(看不到)。
    比如:只能看到汽车的壳子、轮胎等,看不到发动机。
  • 继承:概念的继承关系。

2.4 面向对象的三大特征

封装可以隐藏实现细节,使得代码模块化
继承可以**扩展已存在的代码模块(类);
它们的目的都是:代码重用

多态则是为了实现另一个目的——接口重用
多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

提高代码的复用性(OOP)

2.4.1 封装(encapsulation)/隐藏

一.四种访问控制级别

public:对外公开,访问级别最高
protected:只对同一个包中的类或者子类公开
默认:只对同一个包中的类公开
private:不对外公开,只能在对象内部访问,访问级别最低
在这里插入图片描述

二.封装的概念和原则:

概念:将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

原则:把所有的属性藏起来。

封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法(getter和setter方法)。

三.封装的好处:

使用封装有以下好处:
1、良好的封装能够减少耦合。
2、类内部的结构可以自由修改。
3、可以对成员进行更精确的控制。
4、隐藏信息,实现细节。

(说明:①面向对象的封装性本身并不是单单指private关键字;

②封装后的属性必须通过setter和getter进行访问。)

四.封装范式:
属性封装:private 属性类型 属性名称;

方法封装:private 方法返回值 方法名称(参数列表){}

封装类:

public class Student {
    private String name;//属性封装
    private  int age;

    public String getName() {//get方法获取
        return name;
    }

    public void setName(String name) {//修改,添加判断条件
     if(name.length()>0||name.length()<10){
         this.name=name;
     }else{
         System.out.println("输入姓名格式有误!!!");
     }
    }


    public void setAge(int age) {//修改,添加判断条件
        if(age>=0&&age<=150){
            this.age = age;
        }else {
            System.out.println("输入的年龄不符合规范!!");
        }
    }
    public void StudentMessage(){//普通方法
        System.out.println("学生姓名为:"+this.name+"学生年龄为:"+age);
    }
}

测试类:

public class main {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("张三");
        student.setAge(20);
        student.StudentMessage();
    }
}
五.get和set方法的使用:

①在创建对象过程中,我们常用private修饰,并且使用get与set方法对属性进行访问与修改。

②get/set+属性名(小驼峰命名法)。

③通过公共方法,简介操作类中的属性。

④扩展:被private修饰的属性,不能在外部访问与修改,这句话是错的,后期学习的反射可以。

⑤boolean类型的属性,用get与is方法。

public class Dog {
    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;
    }
}

采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。

六.Java 包(package)
  • 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

包的作用:
1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。

2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

  • Java 使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口(Interface)、枚举(enumerations)和注释(annotation)等。

2.4.2 继承(extends)

  • 子类继承父类(基类、超类)的属性和方法
  • 构造器不能继承!
  • 实例化子类,会递归分配所有父类的空间
  • 子类构造器一定调用父类构造器
  • 类一定有构造器(父类、子类)

继承:用来表达概念上具体化延续的具体概念。
继承:让某个类型的对象获得另一个类型的对象的属性和方法。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

  • 1、子类拥有父类非private的属性和方法。
  • 2、子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
  • 3、子类可以用自己的方式实现父类的方法。
方法的重写(override)
  • 在子类中可以根据需要对从基类中继承来的方法进行重写。
  • 重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
  • 重写方法不能使用比被重写更严格的访问权限
重写与重载

重写(Override):子类中存在与父类的方法的方法名相同、参数相同、返回类型可以不同的方法。

  • 父类与子类之间多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Override)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。

class A {
    public void run(){
        System.out.println("跑步");
    }
}

class B extends A{
    public void run(){
        System.out.println("嘎嘎跑");
    }
}

class mains{
    public static void main(String[] args) {
        B b = new B();
        b.run();
    }
}

重载(Overload):在一个类中定义多个方法名相同,而参数类型、数量或次序不同的方法。

  • 一个类中多态性的一种表现。如果在一个类中定义了多个同名的方法,它们参数列表不同,则称为方法的重载(Overload)
public class Overload {
    public Overload(){
        System.out.println("请输入数字");
    }
    public Overload(int a,int b){
        System.out.println(a+b);
    }

    public Overload(int a,int b,int c){
        System.out.println(a+b+c);
    }

    public static void main(String[] args) {
        new Overload();
        new  Overload(1,2);
        new Overload(1,2,3);
    }
}
  区别: 重载实现于一个类中;
	     重写实现于子类中。

学习继承一定少不了这三个东西:构造器、protected关键字、向上转型

继承中的构造器

子类构造器一定调用父类构造器

  • super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性
  • 构造方法中:任何类的构造方法中,若是构造方法的第一行代码没有显示调用super(…),那么Java默认都会调用super()作为父类的初始化方法。所以super()写不写都无所谓
  • 子类构造器一定调用父类构造器
public class ConstructorDemo {
    public static void main(String[] args) {
        Koo koo = new Koo(); // 调用子类对象
        // 运行结果: FOO
    }
}
class Foo{
    public Foo(){
        System.out.println("FOO");
    }
}
class Koo extends Foo{// 继承Foo
    public Koo(){
        super(); // 调用父类无参构造器
        //若是构造方法的第一行代码没有显示调用super(…)
        // 那么Java默认都会调用super()作为父类的初始化方法。
    }
}

注意:
如果父类没有无参数构造器,就必须在子类中明确指定调用父类的有参数构造器

public class ConstructorDemo {
    public static void main(String[] args) {
        Moo koo = new Moo(); // 调用子类对象
    }
}
class Goo{
    int a;
    public Goo(int a){
        this.a=a;
        System.out.println(a);
    }
}
class Moo extends Goo{// 继承Foo
    public Moo(){
        super(2); //  调用父类的有参数构造器
    }
}
  • 注:
    子类构造器默认调用父类无参数构造器
    super()表示调用父类构造器
    使用 super()调用父类构造器,必须写在子类构造器第一行
    this() 必须写在子类构造器第一行
    有 super()就不能有 this(),两者互斥
protected关键字

java会继承父类中default权限以上的成员

private访问修饰符,对于封装而言,是最好的选择,但这个只是基于理想的世界,有时候我们需要这样的需求:我们需要将某些事物尽可能地对这个世界隐藏,但是仍然允许子类的成员来访问它们。这个时候就需要使用到protected。

父类的private成员不会被子类继承,子类不能访问。
但是子类对象的确包含父类的私有成员。
在这里插入图片描述

2.4.3 多态(polymorphism)

多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法。

  • 多态是同一个行为具有不同的表现形式或形态的能力
  • 同一方法可以根据发送对象的不同而采用不同的行为方式
多态存在的三个必要条件
  • 继承:在多态中必须存在有继承关系的子类和父类
  • 重写:子类对父类中的某些方法进行重新定义
  • 父类引用指向子类对象:Parent p = new Child();(向上转型)
多态的转型分为向上转型和向下转型两种:

向上转型:多态本身就是向上转型过的过程

      使用格式:父类类型 变量名=new 子类类型();
      适用场景:当不需要面对子类类型时,通过提高扩展性,
      或者使用父类的功能就能完成相应的操作。

向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型

      使用格式:子类类型 变量名=(子类类型) 父类类型的变量;
     适用场景:当要使用子类特有功能时。

示例:

public class Polymorphism {
    public static void main(String[] args) {
        // 父类类型 变量名=new 子类类型();
        People p=new Student(); // 向上转型
        p.eat();    // 调用方法
        People t = new Teachers(); // 同上
        t.eat();
        // 使用子类特有功能时
        // 子类类型 变量名=(子类类型) 父类类型的变量;
        Student s = (Student)p;
        s.study();
        Teachers tea=(Teachers)t;
        tea.teach();
    }
}
class People{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Student 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("认真备课");
    }
}

三、补充:抽象类与接口(Interface)

3.1 抽象类

3.1.1什么是抽象类

用abstract定义的类,具有抽象方法的类叫抽象类

3.1.2什么是抽象方法

只有方法的定义没有方法的实现
定义抽象方法的目的就是让,子类必须重写父类的抽象方法

3.2接口:

一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口:全部的方法都是抽象方法,全部的属性都是常量

  1. 接口是特殊的抽象类
  2. 接口用来表示纯抽象概念,没有任何具体的方法和属性
  3. 接口不能实例化,可以定义变量
    Shape s = new Shape();
    错 Shape s = new Circle(); 对
  4. 接口变量可以引用具体实现类的实例
  5. 接口只能被实现(继承),一个具体类实现接口,必须使用全部的抽象方法
  6. 接口之间可以继承(implements)
  7. 一个具体类可以实现多个接口,实现多继承现象 表示:一个概念即是 XXX 也是 XXX
  8. 接口中的属性,默认是常量 public static final
  9. 接口的方法一定是 public abstract 的(默认,可以不写)
  10. 实现一个接口,使用关键字 implements,实现实际上是一种继承关系 接口和实现类是父子类型的关系

抽象类与接口二者区别:

抽象类是对一种事物的抽象,即对类抽象
接口是对行为的抽象

示例:

一个接口就是描述一种能力,接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力。

声明格式:

[访问级别] interface 接口名称 [extends 其他的接口名] {
      // 声明变量
      // 抽象方法
}
public interface login {
    // 接口只有方法的特征没有方法的实现
    String username();// 声明变量
    String password();// 声明变量
    void success();    // 抽象方法
    void failed();    // 抽象方法
}

实现类:

public class Logins implements login{

    @Override
    public String username() {
        return "输入用户名";
    }

    @Override
    public String password() {
        return "输入密码";
    }

    @Override
    public void success() {
        System.out.println("登录成功");
    }

    @Override
    public void failed() {
        System.out.println("登陆失败");
    }
}

总结:

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执着与它共情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值