Java面向对象

Java面向对象

面向对象与面向对象

面向对象的程序设计语言必须有描述对象及其相互之间关系的语言成分。这些程序设计语言可以归纳为以下几类:系统中一切事物皆为对象;对象是属性及其操作的封装体;对象可按其性质划分为类,对象成为类的实例;实例关系和继承关系是对象之间的静态关系;消息传递是对象之间动态联系的唯一形式,也是计算的唯一形式;方法是消息的序列。

面向过程

优点:

流程化使得编程任务明确,在开发之前基本考虑了实现方式和最终结果,具体步骤清楚,便于节点分析。

效率高,面向过程强调代码的短小精悍,善于结合数据结构来开发高效率的程序。

缺点:

需要深入的思考,耗费精力,代码重用性低,扩展能力差,后期维护难度比较大。

面向对象

优点:

结构清晰,程序是模块化和结构化,更加符合人类的思维方式;

易扩展,代码重用率高,可继承,可覆盖,可以设计出低耦合的系统;

易维护,系统低耦合的特点有利于减少程序的后期维护工作量。

缺点:

开销大,当要修改对象内部时,对象的属性不允许外部直接存取,所以要增加许多没有其他意义、只负责读或写的行为。这会为编程工作增加负担,增加运行开销,并且使程序显得臃肿。

性能低,由于面向更高的逻辑抽象层,使得面向对象在实现的时候,不得不做出性能上面的牺牲,计算时间和空间存储大小都开销很大。

面向过程和面向对象有什么区别呢?

简单来讲,就像你去银行取钱,面向过程在意的是你怎么去的银行,走的那一条路,而面向对象不在乎你的路上发生的事,而是在乎你去银行取了多少钱。

类的基本结构

属性:对象数据的描述。
方法:对象的行为。
构造方法:用于实例化对象
内部类:在类中声明的类(inner class)
:分静态块与实例块
类的声明:(访问权限修饰符 + class + 类名)
类的作用:类就是一个模板,定义多个对象共同的属性和方法。

属性

在类中声明,是对对象的描述。

public class Dog {
	int id; // 这是一个属性
	String name; // 很显然,这也是一个属性
    private int age; // 同样,这是一个属性。。。
}

方法

方法可以用来定义对象实例的行为。

方法的优点

  • 使程序变得更简短而清晰。
  • 有利于程序维护。
  • 可以提高程序开发的效率。
  • 提高了代码的重用性。
方法的声明
  • 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
  • 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void
  • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
  • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
  • 方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体
    ...
    return 返回值;
}

举例:

public int add(int a, int b) {
    return a + b;
}

public void swap(Integer a, Integer b) {
    Integer t = a;
    a = b;
    b = t;
}
方法的重载

方法可以有不同的"签名"(参数、返回值类型不同)

就是说一个类的两个方法拥有相同的名字,但是有不同的参数列表

Java编译器根据方法签名判断哪个方法应该被调用。

public int max(int a, int b) {
    return a > b ? a : b;
}

public double max(double a, double b) {
    return a > b ? a : b;
}
方法的重写

假如父类中有一个方法,它的子类想要实现与之前不一样的功能,那么子类就可以不改变方法的签名重写这个方法。

public class Animal {
    // 父类中的方法
    public void eat() {
        System.out.println("eat!!!!!!");
    }
}
public class Cat extends Animal{
	// 子类重写的方法
    @Override // 这是一个注解,可以看成是一个标记,同它的名字一样,是覆盖的意思
    public void eat() {
        System.out.println("double eat!!!!!!");
    }
}

内部类

就是在类中再声明一个类

分为静态内部类和普通内部类两种。

public class Car {
    private int id;
    private String name;
    private double price;

    static class Giveaway {
        private int id;
        private String name;
    }

    public class AfterSales {
        private String phone;
        private String name;
    }
}

有静态代码块和实例块。

public class Car {
    private int id;
    private String name;
    private double price;
    public static int num;
    
    // 实例块:可以用来初始化属性
    {
        id = 1;
        name = "长城";
        price = 10000.223;
    }
    
    // 只能初始化静态变量,也可以在静态块中声明对象
    static {
        num = 10;
        Car car = new Car();
    }
}

Java面向对象

Java面向对象有三大特性:封装继承多态

封装

  • 良好的封装能够减少耦合。
  • 类内部的结构可以自由修改。
  • 可以对成员变量进行更精确的控制。
  • 隐藏信息,实现细节。

实现封装性的方式是使用Java提供的权限修饰符:

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
  • public : 对所有类可见。使用对象:类、接口、变量、方法
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

访问控制:

修饰符当前类同一包内子孙类子孙类(不同包)其他包
public
protected✔/××
default××
private××××

最常用的就是publicprivate 这两个关键字。

使用private 关键字封装数据之后,在外部法直接获取和设置属性,所以就需要设置get方法set方法

get()方法

通过在类中编写方法,就可以获取相关的属性值。

public int getId() {
    return id;
}

public String getName() {
    return name;
}
set()方法

通过在类中编写方法,就可以设置相关的属性值。

public void setId(int id) {
    this.id = id;
}

public void setName(String name) {
    this.name = name;
}
构造方法

创建对象的时候,我们希望直接将属性赋予初始值,这就需要用到构造器(构造方法)。

  • 构造方法的名字必须与定义他的类名完全相同,没有返回类型,甚至连void也没有。
  • 构造方法的调用是在创建一个对象时使用new操作进行的。
  • 构造方法的作用是初始化对象
public Car() {
}

public Car(int id) {
    this.id = id;
}

public Car(int id, String name, double price) {
    this.id = id;
    this.name = name;
    this.price = price;
}

注意:如果没有创建空参构造器,JDK会自动为我们声明空参构造器;如果创建了有参构造器,但是没有创建空参构造器,有参的就会覆盖掉空参的,并且不会为我们自动创建

代码演示:

public class Car {
    private int id;
    private String name;
    private double price;

    public Car() {
    }

    public Car(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

继承

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

需要使用关键字:extends

类的继承格式
class 父类 {
}
 
class 子类 extends 父类 {
}
继承类型

需要注意的是 Java 不支持多继承,但支持多重继承。

继承的特性
  • 子类拥有父类非 private 的属性、方法。
  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
  • 子类可以用自己的方式实现父类的方法。
  • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

代码演示:

// 父类
public class Father {
    private int id;
    private String name;
    private int age;
    public String phone = "123456";

    public void testFather() {
        System.out.println("来自Father类的方法");
    }
}

// 子类
public class Son extends Father {
    private int id;
    private String name;
    private int age;

    public void testSon() {
        System.out.println("Son中的方法");
    }
}

// 测试使用类
public class Main {
    public static void main(String[] args) {
        Son son = new Son();
        System.out.println("Son 从 Father 继承来的属性: " + son.phone);
        son.testFather();
        son.testSon();
    }
}
this

Java的方法不止会传递形式参数,还会传递一个隐式参数,就是当前对象的引用,可以使用this关键字进行表示。

例如我们的setter和构造器:

public void setName(String name) {
    this.name = name;
}

public Car(int id, String name, double price) {
    this.id = id;
    this.name = name;
    this.price = price;
}

this.属性 = 参数 通过这种方式可以将类的属性赋值,同时避免了命名冲突。

所以,this也起到了一种标记的作用,this.方法或this.属性,表示的是类中的属性或方法。

super

与this关键字类似。事不过super表示的当前类的父类。

使用举例:

在父类Father中有两个属性id和name,同样,它的子类Son中也有相同的属性,那么在子类创建构造器的时候可以使用super关键字来利用父类的构造器。

public class Father {
	private int id;
	private String name;
    public Father() {
    }
	public Father(int id, String name) {
		this.id = id;
        this.name = name;
	}
}

public class Son {
    private int id;
    private String name;
    public Son() {
        super();
    }
    public Son(int id, String name) {
        super(id, name);
    }
}
补充

Java中所有类都会隐式的继承一个Object类,换言之,Object就是所有类的父类,即使我们创建的类没有显式的继承它。

多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态的实现方式
  • 方式一:方法的重写
  • 方式二:接口
  • 方式三:抽象类和抽象方法
多态的优点
  • 消除类型之间的耦合关系
  • 可替换性
  • 可扩充性
  • 接口性
  • 灵活性
  • 简化性
多态的必要条件
  • 继承
  • 重写
  • 父类引用指向子类对象:Parent p = new Child();

简单来讲,多态就用父类的名,new子类的对象。

代码实例:

Father obj = new Son();
向上转型

两种转型方法

Son son = new Son();
Father obj = son;

// 通过方法的参数自动进行转型
public void test(Father obj) {
    System.out.println(obj);
}
向下转型
// 正常的向下转型
Father son = new Son();
Son obj = (Son)son;

// 不安全的向下转型,在编辑时不会报错,但是在编译时会出现ClassCastException类型转换异常
Father father = new Father();
Son obj = (Son) father;

补充:

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

// 父类
public class Father {
    private int age;
    private String name;

    public void test() {
        System.out.println("Father 的 test方法");
    }
}

// 子类
public class Son extends Father {

    private int id;
    private int age;
    private String name;

    public void test() {
        System.out.println("Son 的 Test 方法");
    }
}

// 测试类
public class Main {
    public static void main(String[] args) {
        Father obj = new Son();
        obj.test();
    }
}

控制台打印:

Son 的 Test 方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

神烦狗闯入了你的博客

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

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

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

打赏作者

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

抵扣说明:

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

余额充值