Java之面向对象概述,类,构造方法,static,主方法,对象

一、面向对象概述

面向过程

面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。这些都是以什么正在发生为主要目标进行编程,不同于面向对象的是谁在受影响。与面向对象明显的不同就是封装、继承、类。 “面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。“面向过程”也可称之为“面向记录”编程思想,他们不支持丰富的“面向对象”特性(比如继承、多态),并且它们不允许混合持久化状态和域逻辑。 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

面向对象:

面向对象实际上就是对现实世界的对象进行了操作

面向对象程序设计英语Object-oriented programming,缩写:OOP),指一种程序设计范型,同时也是一种程序开发的方法。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。 面向对象(Object Oriented)是一种新兴的程序设计方法,或者是一种新的程序设计规范(paradigm),其基本思想是使用对象、类、继承、封装、多态等基本概念来进行程序设计。从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式。

对象:

Object:表示任意存在的事物。

世间万物皆对象,对象是事物存在的实体。

我们将复杂的问题简单化,就会考虑对象是有哪些事物组成的。一般将对象划分为动态部分和静态部分。

事物也就是对象的静态部分,也就是不能动的部分,称为属性,比如一个人,具备高矮,胖瘦,年龄等属性,而这个人也会哭泣,微笑,行走等行为,也就是动态部分,人通过探讨对象的属性和观察对象的行为了解对象。

在计算机的世界中,面向对象程序设计的思想要以对象来思考问题,首先要将现实世界的实体抽象为对象,然后考虑这个对象具备的属性和行为、

一只鸟飞行为例:

首先抽象出的对象为这只鸟,然后识别个对象具备的静态部分,也就是属性,有两只翅膀,两只脚,体重等等,再然后识别这对象的动态部分,也就是行为,这个对象可以飞行,觅食等等,这些行为都是因为这个对象基于其属性而具有的动作。识别出这些属性和行为之后,这个对象就被定义完成,然后可以根据这个对象的特性来指定飞行的方案。

类:

类是同一类事物即对象的的统称,比如人类,鸟类等。

我们可以说对象属于某一个类,但不能说类属于某一个对象。

类是构造对象是所依赖的规范,比如鸟具有一对翅膀,他们可以依靠翅膀飞行,这样具有相同特性和行为的一类事物就称为类。

可以这样理解,类就是对象的设计图。

面向对象三大特征:

封装,继承,多态

以及第四特征,抽象。

封装:

封装是面向对象编程的的核心思想,将对象的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现的细节。

比如我们使用电脑,只需要使用鼠标键盘操作就可以实现功能,无需知道计算及内部是如何操作的。

我们写一方法,不用知道他是怎么实现的,只要能供我们就可以了。

继承:

当处理一个问题时,可以将一些有用的类保留下来,这些类通常具有相同的属性,甚至相同的方法,当遇到同样的问题时可以拿来复用。比如鸽子和鸟类具有相同的属性和行为,可以在创建鸽子类是将鸟类拿来复用,并且保留鸟类具有的属性和行为。

继承主要是利用特定对象之间的共有属性。例如,矩形是四边形,矩形和四边形具有相同特征,都有四个边,可以将矩形类看做四边形的延伸,矩形复用了四边形的属性和行为,同时添加了矩形独有的属性和行为,比如内角都是直角等,而矩形又延伸出了正方形,正方形复用了矩形的属性和行为,而又添加了正方形独有的属性和行为,比如四边相等。

矩形是四边形的子类,而正方形是矩形的子类。

多态:

将父类对象应用于子类的特征就是多态。

多态性允许以统一的风格编写程序,以处理种类繁多的已存在的类以及相关类。该统一风格可以由父类来实现,根据父类统一风格的处理,就可以实例化子类的对象。由于整个事件的处理都只依赖父类的方法,所以日后只需要维护和调整父类方法就好。这样就降低了维护的难度,节省了时间。

比如有一个螺丝类,具有长度粗细螺纹等属性,我们在创建两个子类,长螺丝类,短螺丝类,他们都继承了螺丝类。他们就具有了相同的特性,比如粗细,螺纹密度等。他们也有不同的特性,比如长短。一个螺丝类延伸出不同的子类,子类继承了父类的特征,子类有具有自己的特征,同样的固定行为,它们可以固定不同的对象,这就是多态化结构。

二、类的特性

1.成员变量:成员变量就是Java中累的属性。

2.成员方法:成员方法就是Java中类的行为。

3.局部变量:如果在成员方法内定义一个变量,那这个变量就是局部变量。

      局部变量是在方法被执行时创建,在方法结束时销毁。局部变量在使用时必须进行赋值操作或被初始化,否则会出现编译错误。

4.局部变量的有效范围:可以将局部变量的有效范围称为变量的作用域,局部变量的有效范围从该变量的声明开始到该变量的结束为止。

在相互不嵌套的作用域中可以同时声明两个名称和类型完全相同的局部变量,这两个变量相互独立,不会相互干扰。

在嵌套区域中,不可以定义名称和类型相同的局部变量。

当类中的成员变量与成员方法中的参数重名时,方法中如何使用成员变量呢?

 this关键字:在类中。this代表类对象本身。

package com.hanqi.maya.model;
public class Book {
    String name="abc";
    
    public void showName(String name){
        System.out.println(name);
    }
    
    public static void main(String[] args){
        Book b=new Book();
        b.showName("123");
    }
}

运行输出的name值是参数值,由此可见方法中调用的name是参数中的name,而不是成员变量

如果是使用this:

package com.hanqi.maya.model;

public class Book {
    String name="abc";
    
    public void showName(String name){
        System.out.println(this.name);
    }
    
    public static void main(String[] args){
        Book b=new Book();
        b.showName("123");
    }
}

权限修饰符

三、类的构造方法

构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。每当类实例化一个对象时,类都会自动调用构造方法。

构造方法就是创建类的对象中运行的方法,也就是对象的初始化方法。

需要注意的是:

在定义构造方法时,构造方法没有返回值,但这与普通没有返回值的方法不同,普通没有返回值的方法使用 public void name() 这种形式定义,但构造方法不需要使用void 关键字进行修饰。

 对象初始化

在构造方法中可以为成员变量赋值,这样当实例化一个本类的对象时,相应的成员变量也将被初始化。如果类中没有明确定义构造方法,则编译器会自动创建一个不带参数的默认构造方法。

如果在类中定义的构造方法都不是无参的构造方法,当试图调用无参构造方法实例化一个对象时,编译器会报错。所以只有在类中没有定义任何构造方法时,编译器才会在该类中自动创建一个不带参数的构造方法。

 简单来说:

如果我们不定义构造参数,当我们调用无参构造方法实例化一个对象时,会自动创建一个无参数构造方法

当我们定义了一个无参数构造方法,当调用无参构造方法实例化一个对象时,不会报错

当我们定义的构造方法都不是无参的构造方法,当试图调用无参构造方法实例化一个对象时,编译器会报错

当我们只定义了无参数构造方法,当调用构造方法实例化一个对象时给他传入参数,编译器会报错

使用this关键字,还可以调用类中的构造方法来简化代码

例子:

我们假设这样一种情况,我们去开会,每个人默认发一瓶水,如果有需要可以要多瓶水,用this调用构造方法来简化代码

    public class White {
    protected int nwhite;
    public White(){
        /*nwhite=1;
        System.out.println("给您"+nwhite+"瓶水");
        以上两行代码的效果和下面一行代码相同
        */
        //用this来调用本身的实参构造方法,来传入一个参数1,代表默认一瓶水
        this(1);
    }
    public White(int nwhite){
        this.nwhite=nwhite;
        System.out.println("给您"+nwhite+"瓶水");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        White w1=new White();
        White w2=new White(5);
    }
}

私有构造方法

构造方法和其它方法一样,也可以用private修饰,私有的构造方法无法在本类外部使用,也就导致本类无法用new实例化,这样可以控制对象的生成。

四、static静态修饰符

由static修饰的变量,常量,和方法被称作静态变量、静态常量、和静态方法。他们都存放在内存的“”静态区”中,这些变量和方法有独立的生存周期。

内存中的静态区在整个程序运行结束之后才会释放,所以用静态修饰的代码的生命周期,是整个程序的生命周期。

静态区:内存中的静态区的变量可以被本类共享,其他类调用本类静态变量和静态方法时,无需实例化就可以调用。

静态变量

很多时候,不同的类之间需要对同一个变量进行操作,比如一个水池,同时打开入水口和放水口,进水和出水这两个动作会同时影响到池中水量,这是池中水量就是一个共享的变量。在Java中,我们把共享的变量用static修饰,该变量就是静态变量。

public class Pool {
    public static int white;
    
    public void inWhite(){
        white+=3;
        System.out.println("进水一次");
    }
    public void outWhite(){
        if(white>=5){
            white-=5;
            System.out.println("放水一次");
        }else{
            white=0;
        }
    }
    public static void main(String[] args) {
        Pool in=new Pool();
        Pool out=new Pool();
        in.inWhite();
        System.out.println("水量:"+Pool.white);//这里的Pool.white,in.white,out.white所代表的是同一个变量
        in.inWhite();
        System.out.println("水量:"+in.white);
        out.outWhite();
        System.out.println("水量:"+out.white);
    }
}

同一个类的不同实例对象,共用同一个静态变量,如果一个对象将其改变,另一个对象的静态变量也会改变。

public class Test {
    public static int x;
    public int y;
    
    public  Test(int x,int y){
        this.x=x;
        this.y=y;
    }
    public static void main(String[] args) {
        Test a=new Test(0,1);    //给x传0  给y传1
        Test b=new Test(11,111);    //给x传11  给y传111
        System.out.println("a的x的值:"+a.x);
        System.out.println("a的y的值:"+a.y);
        System.out.println("b的x的值:"+b.x);
        System.out.println("b的y的值:"+b.y);
    }
}

我们可以看出,静态变量的值改变了

如下图所示,两个对象x静态变量同时指向了同一块内存区域,而非静态变量y则是指向了不同的区域。

当a.x给静态变量赋值,b.x又对静态变量重新复制,导致了a.x指向的是b.x的新值。

静态常量

用final static修饰一个成员变量,这个成员变量就会变成一个静态常量。

举个例子来看如何使用一个静态常量,比如我们计算圆的面积和球的体积时,都会用到 π 的值,这是我们就可以定义一个 PI 来作为静态常量存放 π 的值,而不必去重复定义。

package com.hanqi.maya.model;

public class Grap {
    final static double PI=3.1415926;
    //PI 作为静态常量,应该大写,PI的值不可以被修改
    public static void main(String[] args) {
        Cir c=new Cir(3);
        Sph s=new Sph(3);
    }
    
}
class Cir{
    double r;
    double m;
    public Cir(double r){
        this.r=r;
        m=Grap.PI*r*r;
        System.out.println("圆的半径:"+r);
        System.out.println("圆的面积:"+m);
    }
}

class Sph{
    double r;
    double vol;
    
    public Sph(double r){
        this.r=r;
        vol=4/3*Grap.PI*r*r*r;
        System.out.println("球的半径:"+r);
        System.out.println("球的体积:"+vol);
    }
}

静态方法

我们知道如果想要使用类中的成员方法,需要先将这个类进行实例化,但有些时候我们不想或者无法创建对象时,还要调用类中的方法才能够完成业务逻辑,此时我们就可以使用静态方法。调用类的静态方法,无需创建对象。

public class Staticd {
    public static void show(){
        System.out.println("这是静态方法show()");
    }
    public static void main(String[] args) {
        //不需要通过 new 实例化,直接通过 类名 . 调用就可以使用静态方法
        Staticd.show();
    }
}

补充:System.out.println( ); 方法就是一个典型的静态方法,我们没有创建System对象,就实现了输出功能,类中的 maiin 方法同样也是静态方法。

静态代码块

在类中的成员方法之外,用static修饰代码区域可以称之为静态代码块,定义一块静态代码块,可以完成类的初始化操作,在类声明时就会运行。

public class Staticd {
    
    {
        System.out.println("这里是非静态代码块");
    }
    //静态代码块会在非静态代码块之前运行,跟写的位置无关
    static{
        System.out.println("这里是静态代码块");
    }
    public Staticd(){
        //构造方法 在 new 的时候运行
        System.out.println("这里是构造方法");
    }
    //成员方法在调用的时候运行
    public void method1(){
        System.out.println("这里是成员方法  1");
    }
    public void method2(){
        System.out.println("这里是成员方法  2");
    }
    public static void main(String[] args) {
        Staticd test =new Staticd();
        test.method1();
    }
}

有运行结果我们可以得出:

1.静态代码块在非静态代码块之前运行

2.构造方法在new的时候运行

3.成员方法在调用的时候运行,不调用不运行

4.运行的优先顺序如上图所示

五、类的主方法  main 方法

主方法是类的入口点,他定义了程序从何处开始:主方法提供对程序流向的控制,Java编译器通过主方法来执行程序。

注意:

主方法是静态的,所以要直接在主方法中调用其他方法德华该方法必须也是静态的。

主方法没有返回值。

主方法的形参是数组。

六、对象的特性

对象的创建

Java中使用 new 操作符调用构造方法就可以创建一个对象。

对象的引用

在Java中一切都可以看作是对象,但真正的操作标识符实质上是一个引用。

引用只是存放了一个对象的内存地址,并非存放了一个对象,严格的说引用和对象是不同的,但是可以将这种区别忽略,如可以简单的说book是Book类的一个对象,而事实上应该是book包含Book对象的一个引用。

public class Book {
    String name="《Java》";
    public String getName(){
        return name;
    }
    public static void main(String[] args) {
        Book b=new Book();
        System.out.println(b.getName());
                //输出的结果完全相同    
        System.out.println(new Book().name);
    }
}

输出的结果完全一样, b.getName()  和  new Book().name 是一样的,说明  new Book() 才是一个真正的对象实体,而  b  只是一个引用,他指向了new Book() 的内存地址。

对象的使用

当用户用new操作符创建了一个对象之后,可以使用 “对象.类成员” 来获取对象的属性和行为。对象的属性和行为在类中是通过类成员变量和成员方法的形式来表示的,所以当对象被实例化之后,也就获得了相应的属性和行为。

public class Test1 {
    public int i=10;
    public void Call(){
        System.out.println("调用Call方法");
        for(i=0;i<3;i++){
            System.out.print(i+" ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        Test1 t1=new Test1();
        Test1 t2=new Test1();
        System.out.println("t1.i:"+t1.i);
        t1.Call();    //使用成员方法输出成员变量的值
        t2.i=5;    //利用对象来调用类的成员
        System.out.println("t2.i:"+t2.i);
        t2.Call();
    }
}

对象的销毁

每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址将被回收。在其它语言中需要手动回收废弃的对象,但是Java又有一套完整的垃圾回收机制,用户不必担心废弃的对象占用内存,垃圾回收器将回收无用但占内存的资源。

补充:finalize()方法

finalize()是所有类的父类 Object 提供的方法

如果用户在类中定义了finalize()方法,在垃圾回收是首先调用该方法,并且在下一次垃圾回收动作发生时,才能真正回收被对象占用的内存。

垃圾回收器只能回收用new创建的对象,如果某些对象不是通过new在内存中获取了一块区域,这种对象可能不会被垃圾回收系统识别。

由于垃圾回收不受人为控制,具体执行时间也不确定,所以finalize() 方法也就无法执行,为此,Java提供了System.gc()方法强制启动垃圾回收器。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

Python语言中list及tuple的使用示例

Python语言中的list Python有一种内置数据类型被称为列表:list。 1.list基本定义 list是一种有序的集合,可以随时添加和删除其中的元...

33470
来自专栏C语言C++游戏编程

有人@我,你有一份C语言基础大全手册要领取,快来拿!

前两天,有网友问了我一个关于C语言的问题,本着认真装逼的态度,我把大学时学过的C语言课本翻了一遍,终于找到了答案。整理后,现分享给大家!

19420
来自专栏从零开始学自动化测试

python笔记2-冒泡排序

前言 面试的时候经常有面试官喜欢问如何进行冒泡排序?这个问题相信能难倒一批英雄好汉,本篇就详细讲解如何用python进行冒泡排序。 一、基本原理 1.概念: 冒...

38760
来自专栏五分钟学算法

每天一算:Reverse Linked List II

变换的是2,3,4这三个点,那么我们可以先取出2,用front指针指向2,然后当取出3的时候,我们把3加到2的前面,把front指针前移到3,依次类推,到4后停...

12510
来自专栏老九学堂

【必读】超全的C语言基础知识大全

我们用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,加深小伙伴们对C语言的认识。

34220
来自专栏老马说编程

计算机程序的思维逻辑 (15) - 初识继承和多态

继承 上节我们谈到,将现实中的概念映射为程序中的概念,我们谈了类以及类之间的组合,现实中的概念间还有一种非常重要的关系,就是分类,分类有个根,然后向下不断细化...

22190
来自专栏HappenLee的技术杂谈

C++雾中风景7:闭包

闭包(closure)是函数式编程的重要的语法结构。 闭包的概念其实很简单,一言以蔽之:闭包是带有上下文的函数。说白了,就是有状态的函数。也就是说一个局部变量...

13620
来自专栏柠檬先生

你不知道的javaScript笔记(4)

类型: JavaScript 有7种内置类型 空值 (null) 未定义(undefined) 布尔值(boolean) 数字(number) 字符串(stri...

23050
来自专栏xingoo, 一个梦想做发明家的程序员

【面试虐菜】—— JAVA面试题(1)

今天参加笔试,里面有设计模式,和一些基础题! 印象最深的是:什么不是Object的函数,我蒙的finalize,哎,无知! 还问了,接口与抽象类的不同,还...

22090
来自专栏Micro_awake web

JavaScript实现八大内部排序算法

? 注:基数排序中:r是关键字的基数,d是长度,n是关键字的个数 1.插入排序 基本思想:在序号i之前的元素(0到i-1)已经排好序,本趟需要找到i对应的元素...

25390

扫码关注云+社区

领取腾讯云代金券