Java面向对象

Java面向对象

面向对象与面向过程的区别

面向过程面向对象
设计思路自顶向下、层次化、分解自底向上、对象化、综合
程序单元函数模块对象
设计方法程序=算法+数据结构程序=对象=数据+方法
优点相互独立,代码共享,性能相对较高接近人的思维方式, 使用灵活,易维护、易复用、易扩展
缺点修改、维护困难性能相对较低

1.面向对象的概念

面向对象编程是一种编程范式,它使用“对象”来设计软件。对象可以包含数据(通常称为属性或字段)和代码(通常称为方法)。在Java中,几乎一切都是对象,包括基本数据类型(如int和char)都是对象的特例。

面向对象编程的四个主要原则是:

1.封装(Encapsulation):封装是关于隐藏对象的内部状态和行为细节,只暴露必要的操作接口。在Java中,这通常通过使用访问修饰符(如private, protected, public)来实现。

2.继承(Inheritance):继承允许创建一个类(称为子类或派生类)来继承另一个类(称为父类或基类)的属性和方法。这有助于代码复用和创建层次结构。Java支持单继承,即一个类只能直接继承自一个父类,但可以通过接口实现多重继承的效果。

3.多态(Polymorphism):多态意味着同一个操作作用于不同的对象,可以有不同的解释或不同的行为。在Java中,多态主要通过方法重载(overloading)和方法重写(overriding)来实现。多态性允许我们编写更通用的代码,可以处理不同类型的对象。

4.抽象(Abstraction):抽象是简化复杂现实世界问题的过程,只保留与当前问题相关的属性和方法。在Java中,抽象可以通过抽象类和接口来实现。抽象类可以包含抽象方法(没有具体实现的方法),而接口则定义了一组方法规范,由实现该接口的类来具体实现。

1.1如何建立面向对象的思维呢?

1、先整体,再局部
2、先抽象,再具体
3、能做什么,再怎么做

1.2面向对象的优势

  • 可重用性:代码重复使用,减少代码量,提高开发效率。面向对象的三大基本特征(继承、封装和多态)都围绕这个核心。
  • 可扩展性:指新的功能可以很容易地加入到系统中来,便于软件的修改。
  • 客观理性:能够将功能与数据结合,方便管理。

2.类与对象

类(Class)

  • 定义对象的蓝图,包括属性和方法。
  • 示例:public class Car { ... }

类:用来描述一类具有相同特征(属性)和相同行为(方法)的对象。

对象(Object)

对象(Object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。

它们是有形的,如一个人、一件物品;也可以是无形的,如一个计划、一次交易。

类和对象的关系:

  • 类是对象的抽象
  • 对象是类的实例化

定义格式:

 类的定义:
class 类名称{
属性名称;
返回值类型 方法名称(){}
}

对象的定义:
一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:
类名称 对象名称 = new 类名称() ;

如果要想访问类中的属性或方法(方法的定义),则可以依靠以下的语法形式:
访问类中的属性:对象.属性 ;
调用类中的方法:对象.方法();

全局变量(成员变量) 定义在方法的外部,类的内部。使用范围是整个类 不需要初始值 存储在堆内存中(对象存在时才在存在) 局部变量 (方法中的变量)

定义在方法的内部或者某一个语句块的内部,适用范围仅限于方法内或者语句块内 必须有初始值 存储在栈内存中 成员方法 语法:

访问修饰符 返回值类型 方法名称(参数列表){ 方法体 }

访问修饰符:public 返回值类型由返回值决定 成员变量可以直接在成员方法中使用,但是main方法中如果调用成员变量和方法必须通过对象.属性名\方法名(参数列表)的形式来调用

成员方法之间的调用,直接写方法名(参数列表)即可

构造方法 对象一建立就会调用构造方法,可以创建对象,给成员变量(属性)初始化。

方法名和类名相同 没有返回值和void,没有return 不能被static等关键字修饰 可以方法重载(定义多个参数列表不同的构造方法) 当一个类中没有写构造方法时,系统会默认给该类一个默认的无参构造方法。当自己定义构造方法后默认的构造方法就不存在了。(自己定义有参的构造方法后,如果还想使用无参的构造方法,就要自己再添加一个无参的构造方法)

public class Animal {
 String name;
 int age;
 //构造方法
 public Animal(){
 System.out.println("------无参的构造方法------");
 name = "动物";
 age = 0;
}
public Animal(String name,int age){
    System.out.println("------有参的构造方法------");
    this.name = name;
    this.age = age;
}

public static void main(String[] args) {
    //创建对象
    Animal a1 = new Animal();
    System.out.println(a1.name+","+a1.age);

    Animal a2 = new Animal("兔子",2);
    System.out.println(a2.name+","+a2.age);
}
}

在没有static关键字修饰的方法中使用

this关键的字用来区分成员变量和局部变量同名的情况:

public class Student{
 //成员变量
 String name;
 int age;
 int classNum;
public Student(String name,int age,int classNum){    
    //s1调用了构造方法,所以这里的this代表s1对象
    this.name = name; //成员变量name=局部变量name
    this.age = age;
    this.classNum = classNum;
}

public static void main(String[] args){
    Student s1 = new Student("张三",18,1);
    System.out.println(s1.name);//打印 张三
}
}

this关键字在构造方法中的第一行以 this(参数列表) 的形式出现时,就表示当前构造方法调用了该类中其他的构造方法(于参数列表相匹配的构造方法):

public class Test1 {

public Test1(){
    this("张三",18);
}
public Test1(String name,int age){
    System.out.println("姓名:"+name+",年龄:"+age);
}

public static void main(String[] args) {
    Test1 test1 = new Test1();
}
}

3.方法的重写和重载

方法的重写规则

  • 参数列表与被重写方法的参数列表必须完全相同。

  • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。

  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。

  • 父类的成员方法只能被它的子类重写。

  • 声明为 final 的方法不能被重写。

  • 声明为 static 的方法不能被重写,但是能够被再次声明。

  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

  • 构造方法不能被重写。

  • 如果不能继承一个类,则不能重写该类的方法。

    重载(Overload)

    重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

    每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

    最常用的地方就是构造器的重载。

    重载规则:

    • 被重载的方法必须改变参数列表(参数个数或类型不一样);

    • 被重载的方法可以改变返回类型;

    • 被重载的方法可以改变访问修饰符;

    • 被重载的方法可以声明新的或更广的检查异常;

    • 方法能够在同一个类中或者在一个子类中被重载。

    • 无法以返回值类型作为重载函数的区分标准。

      重载与重写的区别

      区别点重载方法重写方法
      参数列表必须修改一定不能修改
      返回类型可以修改一定不能修改
      异常可以修改可以减少或删除,一定不能抛出新的或者更广的异常
      访问可以修改一定不能做更严格的限制(可以降低限制)

4.封装

封装的优点

    1. 良好的封装能够减少耦合。
    1. 类内部的结构可以自由修改。
    1. 可以对成员变量进行更精确的控制。
    1. 隐藏信息,实现细节。封装性是面向对象思想的三大特征之一,封装就是隐藏实现细节,仅对外提供访问接口。实现细节部份包装、隐藏起来的方法。
      封装有:属性的封装、方法的封装、类的封装、组件的封装、模块化封装、系统级封装…
      封装的好处:模块化、信息隐藏、代码重用、插件化易于调试、具有安全性
      封装的缺点:会影响执行效率封装之前:属性都可以直接访问和修改
      class Person{
        String name;
        int age;
      }封装之后:
      class Person{
        //属性是成员变量,私有化属性,使得其他对象不能直接访问属性
        private String name;
        private int age;
        //参数及方法内定义的变量是局部变量
        public void setName(String name){
        this.name = name;}
        public String getName(){
        return name;}
      }成员变量和局部变量的区别
      a、在类中的位置不同
      成员变量:在类中定义
      局部变量:在方法中定义或者方法的参数
      b、在内存中的位置不同
      成员变量:在堆内存(成员变量属于对象,对象进堆内存)
      局部变量:在栈内存(局部变量属于方法,方法进栈内存)
      c、生命周期不同
      成员变量:随着对象的创建而存在,随着对象的销毁而消失
      局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
      d、初始化值不同
      成员变量:有默认初始化值,引用类型默认为null
      局部变量:没有默认初始化值,必须定义,赋值,然后才能使用
      注意:
      局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。

5.继承

   继承的特性:

  • 子类拥有父类非 private 的属性、方法。

  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

  • 子类可以用自己的方式实现父类的方法。

  • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

继承关键字

继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承 Object(这个类在 java.lang 包中,所以不需要 import)祖先类。

继承中的构造方法 创建有继承关系的子类对象时,会先执行父类中默认的构造方法,然后执行子类中相关的构造方法 如果父类中不存在默认的构造方法,那么此时的解决问题,第一种就是手动添加一个默认的构造方法。 super关键字 表示当前类的父类的引用 只能出现在有继承关系的子类中 super两种用法: super.属性名、super.方法名(参数列表) 表示父类的属性和方法,和子类中的属性或方法重名时使用 super(参数列表) 出现在子类构造方法的第一句代码时(super不能与this连用) 就是通过参数列表匹配父类的构造方法来创建父类对象

super 与 this 关键字

**super 关键字:**我们可以通过 super 关键字来实现对父类成员的访问,用来引用当前对象的父类。

**this 关键字:**指向自己的引用,引用当前对象,即它所在的方法或构造函数所属的对象实例。。

final 关键字

final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。

final 含义为 "最终的"。

使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:

  • 声明类:

    final class 类名 {//类体}

  • 声明方法:

    修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

构造器

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

class SuperClass {
    private int n;

    // 无参数构造器
    public SuperClass() {
        System.out.println("SuperClass()");
    }

    // 带参数构造器
    public SuperClass(int n) {
        System.out.println("SuperClass(int n)");
        this.n = n;
    }
}

// SubClass 类继承
class SubClass extends SuperClass {
    private int n;

    // 无参数构造器,自动调用父类的无参数构造器
    public 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;

    // 无参数构造器,调用父类中带有参数的构造器
    public 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);
    }
}

6.多态

多态就是同一函数在不同类中有不同的实现;

  • 面向对象的多态性,即“一个接口,多个方法”。
  • 多态性体现在父类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式。
  • 多态性允许一个接口被多个同类使用,弥补了单继承的不足。

多态的实现方式

方式一:重写:方式二:接口方式三:抽象类和抽象方法

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值