Java 7天劝退(三)-面向对象编程

本文介绍了Java的面向对象特性,包括封装、继承和多态。讲解了类与对象的概念,详细阐述了属性和方法、构造器、this关键字以及方法重载等核心概念,强调了封装在面向对象编程中的重要性。
摘要由CSDN通过智能技术生成

面向对象

简介

面向过程的操作是以程序的基本功能实现为主,开发的过程中只是针对问题本身的实现,并没有很好的模块化的设计,所以在进行代码维护的时候较为麻烦。而面向对象,采用的更多的是进行子模块化的设计,每一个模块都需要单独存在,并且可以被重复利用。总的来说面向对象关注的是对象本身,既模块化的设计,
特征主要有封装,继承,多态

封装

继承

多态

类与对象

基本概念

类和对象的关系:类实际上是表示一个客观世界中某类群体的一些基本特征抽象,属于抽象的概念集合,对象就是表示一个个具体的事物。
例如,在现实生活中,人就可以表示为一个类,因为人本身属于一种广义的概念,并不是一个具体个体描述。而某一个具体的人,如张三同学,就可以称为对象,

定义语法

类:类是由属性和方法组成的。属性就是一个变量,方法是一些操作的行为
在这里插入图片描述

说明:

  • 类:类是由属性和方法组成的
  • 常见名称:
    属性=成员变量=filed=域,字段
    方法=成员方法=函数=method
    创建类的对象=类的实例化=实例化类
    例如:
 class Person{//定义一个Person类
    String name;//人名
    int age;//年龄
    boolean isMale;//是否为男性
    public void eat() {//调用对象的行为
        System.out.println("我在吃饭");
    }
}
//类的使用
public class ObjTest {
    public static void main(String[] args) {
        //创建对象
        Person person = new Person();
        //调用对象的结构
        person.name="Java";
        person.age=10;
        person.isMale=true;
        System.out.println(person);
        person.eat();
        }
  • 内存解析:数据类型的执行分析就必须结合内存操作来看。下面给出两块内存空间的概念。
  • 堆内存(heap):保存每一个对象的属性内容,堆内存需要用关键字new才可以开辟,如果一个对象没有对应的堆内存指向,将无法使用;
  • 栈内存(stack):保存的是一块堆内存的地址数值,可以把它想象成一个int型变量(每一个int 型变量只能存放一个数值),所以每一块栈内存只能够保留一块堆内存地址。

个人理解:下面换个角度来说明这两块内存空间的作用。 掌握以上内存分析方法对于程序理解与概念应用是非常重要的。

  • 堆内存:保存对象的真正数据,都是每一个对象的属性内容;
  • 栈内存:保存的是一块堆内存的空间地址,但是为了方便理解,可以简单地将栈内存中保存的数据理解为对象的名称(Person person),就假设保存的是“person”对象名称
    在这里插入图片描述
    上面的例子的内存解析
    内存解析 说明
    在所有的引用分析里面,最关键的还是关键字“new”。一定要注意的是,每一次使用关键字new 都一定会开辟新的堆内存空间,所以如果在代码里面声明两个对象,并且使用了关键字new为两个对象 分别进行对象的实例化操作,那么一定是各自占有各自的堆内存空间,并且不会互相影响。

属性(成员变量)和局部变量

相同点:

  • 定义格式:数据类型 变量名=变量值;
  • 先声明后使用
  • 量都有其对应的作用域

不同点:

  • 声明位置不同:属性:定义在{},局部变量:声明在方法内,形参,代码块,
  • 修饰符不同:属性:使用属性修饰符,包括public,protected,default,private;局部变量:使用不了
  • 默认初始化值:属性:类的属性:根据类的属性都有初始化值;局部变量:无初始化值。我们在调用局部变量,必须显性赋值。注意:形参在调用是,直接赋值即可
  • 内存加载位置不同:属性:堆(非static); 局部变量:栈

方法的重载

方法重载

在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。体现了多态性

public class OverLoadTest {
    public static void main(String[] args) {
        OverLoadTest overLoadTest=new OverLoadTest();
        overLoadTest.getSum(1,2);
        overLoadTest.getSum(1.2,1.5);
        overLoadTest.getSum(1,1.5);
    }
    //下面3个方法体现了重载
    public void getSum(int i,int j){
        System.out.println(i + j);
    }
    public void getSum(double i,double j){
        System.out.println(i + j);
    }
    public void getSum(int i,double j){
        System.out.println(i + j);
    }

}

说明

  • 是否重载跟方法的权限修饰符,返回值类型,形参,方法体没有关系。
  • 调用方法时候,如何确定某个指导方法:方法名–>参数列表

可变形参

  1. jdk1.5新增的内容.
  2. 使用格式: 格式:数据类型…变量名
public static void main(String[] args) {
        MethodArgsTest methodArgsTest = new MethodArgsTest();
        methodArgsTest.show(123);
        methodArgsTest.show("hello");
        methodArgsTest.show("hello","world");
    }
    //重载
    public void show(int i){
        System.out.println("i="+i);
    }
    public void show(String str){
        System.out.println("str="+str);
    }
    //调用可变个数的形参方法
    public void show(String... str){
        Arrays.stream(str).forEach(System.out::println);
    }

说明

  • 当调用可变个数的形参方法时,数量可以是1,2,3甚至是多个,与本类的其他同名的方法构成重载
  • jdk1.5之前使用String[]传入,后使用String…,两者不构成重载
  • 必须声明在形参列表末尾,可变形参最多只有一个
 public void show(String...str,int j){}//错误,Vararg parameter must be the last in the list

方法引用传递

引用传递是整个Java的精髓所在,而引用传递核心意义是:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同一堆内存进行内容的修改。下面例子

public static void main(String[] args) {
        int m=10;
        int n=20;
        ValueTransferTest1 valueTransferTest1 = new ValueTransferTest1();
        valueTransferTest1.swap(10,20);
        System.out.println("m="+m+",n="+n);
    }
    public void swap(int m,int n){
        int temp=m;
        m=n;
        n=temp;
    }
m=10,n=20

内存解析:如下
在这里插入图片描述
形参与实参: 形参方法声明的参数,实参方法调用是实际传给形参的参数值
如果是基本数据类型:实参–>形参,数据值
如果是英语数据类型:实参–>形参,地址值

递归

自己调用自己本身,必须含有终止条件,递归体
举例:菲波那次数列。

面向对象特征:封装

封装

封装是面向对象的方法所应遵循的一个重要原则。它有两个含义:一层含义是指把对象的属性和行为看成一个密不可分的整体,将这两者“封装”在一个不可分割的独立单位(即对象)中;另一层含义指信息隐蔽,把不需要让外界知道的信息隐藏起来。隐藏对象内部的复杂性,只提供公开的接口,便于外部调用。

public class BookTest {
    public static void main(String[] args) {
        Book book = new Book();
        book.setTitle("Java开发");
        book.setPrice(-99.0);
        book.getInfo();
    }
}
class Book{
    /*书的名字*/
    private String title;
    /*书的价格*/
    private Double price;
    /*此方法将由对象调用*/
    public void getInfo() {
        System.out.println("图书名称:" + title + ",价格:" + price);
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Double getPrice() {
        return price;
    }
    //数据验证
    public void setPrice(Double price) {
        this.price = price>0?price:null;
    }
}

上面体现了使用private封装属性。
封装性的体现

  1. 属性的私有化,同时提供公共的方法来获取(getXxx)和设置(setXxx)
  2. 不对外暴露的私有方法
  3. 单例模式

权限修饰符

用来修饰成员的访问权限,从大到小,pubic,protected,缺省(default)
权限修饰说明:

  1. 四种都能修饰类的内部结构,包括方法,属性,构造器,内部类
  2. 修饰类只能用public 缺省

构造器

构造器(构造方法):在实例化类前,可能在对象实例化时为其进行一些初始化的准备操作,这个时候就需要构造方法的支持。构造方法本身是一种特殊的方法,它只在新对象实例化的时候调用,其定义原则是:方法名称与类名称相同,没有返回值类型声明,同时构造方法也可以进行重载。 相当于在new 某类之前的一个初始化方法
作用:

  1. 创建对象
  2. 初始化信息

格式:

权限修饰符 泪目(形参列表){}//注意格式不能用void修饰

例子:

 	public static void main(String[] args) {
        //空参构造
        Uesr uesr = new Uesr();
    }
    class Uesr{
    //成员变量(属性)
    String name;
     public  Uesr(){
        System.out.println("Uesr.User");
    	}
    }
Uesr.User

可以看见当new User()的时候,调用了空参构造器的方法,本程序在User类中定义了一个构造方法,可以发现构造方法的名称与User类名称相同,没有返回值声明,并且构造方法只有在使用关键字new实例化对象时才会被调用一次。
说明
一旦显式定义了类的构造器之后,系统不在提过默认的空参构造器。
提问:构造方法与普通方法的区别?
构造方法与普通方法的调用时机不同。
首先在一个类中可以定义构造方法与普通方法两种类型的方法,但是这两种方法在调 用时有明显的区别:

  • 构造方法是在实例化新对象(new)的时候只调用一次;
  • 普通方法是在实例化对象产生之后,通过“对象.方法”调用多次。
    如果在构造方法上使用了void,其定义的结构与普通方法就完全一样,而程序的编译是依靠定义结构来解析的,所以不能有返回值声明。

this关键字

this修饰属性,方法,构造器;
当getXxx()和setXxx()形参和实参名相同时候,可以使用this表示当前对象的属性。

public class Person {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
    		this.name = name;
        //name = name;编译器识别不了name是当前类的属性还是方法的形参;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
        //age = age;同理
    }
    //构造器中也可以使用this
     public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

this只能调用其他构造器,格式为this(形参列表)

public class Person {
    private String name;
    private Integer age;

    public Person(){
        System.out.println("Person.Person");
    }
    public Person(String name,Integer age){
        //调用无参构造器
        this();
        this.name=name;
        this.age=age;
    }
}
public class PersonTest {
    public static void main(String[] args) {
        Person java = new Person("JAVA",0);
    }
}
Person.Person

注意:this不能掉用自己,内部最多只能声明一次this(形参)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值