JAVA 初学面向对象

面向对象

对于java初学者而言,来到面向对象这章而言,肯定会有许多困惑,比如:对象是什么?对象是怎么创建的?对象可以用来干什么、为什么要面向对象?而不是基于面向对象,更有人会对面向过程和面向对象这两概念产生混淆,接下来就来跟我一起解决这些问题。

首先我们先把这个易混淆概念来讲解一下,不懂的同学可以先听一下,听完这些在解决其他问题,可能会有更大的帮助。

面向对象思想

面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。面向对象有三大特征:封装性、继承性、多态性,其中封装性指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。对于继承性,就是两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就提高了代码的复用性。继承是作为多态的前提的。多态是说父类或接口的引用指向了子类对象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性,但是多态有一点不好之处在于:父类引用不能访问子类中的成员的特有方法和属性。

封装思想

所谓封装,就是将属性和方法捆绑到一起,封装到一个对象中zhi去,简单的说,你是人,你有许多属性,比如说dao你的姓名,年龄,身高,体重,性别,性格,爱好等等,这是属性;而同时,你又会吃饭,睡觉,工作,学习,做事情,这些是方法,是你所具有的;同时将属性和方法封装到一个类中去,就能很完美的描述这个类的特征了,同时,它所具有的方法也就一起集成到类中,方便使用,这些是简单的描述了。官方一点说就是:封装是将事物的一些不便暴露给外界的一些属性隐藏起来.同时给外界提供一些接口,用来和外界进行交互,建立连接关系。

封装的优点:(1)隐藏类的实现细节;(2)让使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制 逻辑,限制对属性的不合理操作;(3)便于修改,增强代码的可维护性;

易混淆概念

 

“面向对象”和“基于对象”

面向对象的三大特点(封装,继承,多态)缺一不可。通常“基于对象”是使用对象,但是无法利用现有的对象模板产生新的对象类型,继而产生新的对象,也就是说“基于对象”没有继承的特点。而“多态”表示为父类类型的子类对象实例,没有了继承的概念也就无从谈论“多态”。很多流行技术都是基于对象的,它们使用一些封装好的对象,调用对象的方法,设置对象的属性。但是它们无法让程序员派生新对象类型。他们只能使用现有对象的方法和属性。所以当你判断一个新的技术是否是面向对象的时候,通常可以使用后两个特性来加以判断。“面向对象”和“基于对象”都实现了“封装”的概念,但是面向对象实现了“继承和多态”,而“基于对象”没有实现这些

 

“面向对象”和“面向过程”

他们都是解决问题的思路(大致的方向),但是要他们对于同一问题的解决思路是不一样的。

可以拿生活中的实例来理解面向过程与面向对象,例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用不同的方法来实现。

如果是面向对象的设计思想来解决问题。面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

简而言之:面向过程就是一个执行者,凡事都要自己亲力亲为;面向对象就是一个指挥者,需要让别人就帮你解决问题。

注意:高能预警!!!!!!

面向对象和面向过程一定是互斥的吗? 肯定不是。

我们在处理问题时可以完全的面向过程,但是不能完全面向对象,举个栗子:“你想吃饭”

你让女朋友做饭 你这个角度而言 面向对象
从女朋友这个角度而言呢?如果女朋友做---》面向过程;如果女朋友不做 叫外卖---》 面向对象
从餐馆这个角度而言呢?应该是要做饭---》 面向过程;如果餐馆不做 可以叫别家餐馆做---》面向对象
.....别的餐馆都不做 ,这个饭始终没人做, 相互踢皮球,最终问题也不会被解决
从中可以看出什么————这个事最终要被处理必须面向过程。

所以 面向过程其实是最基本的思路 而面向对象是基于面向过程的思路。


从上面的长篇巨幅了解完之后,对于我们学习java的,刚开始都是程序员,所以我们需要写很多代码,在宏观上而言,写代码啊就是在面向过程,只不过在某个时刻,某一行代码,我们会用到面向对象的东西。

    System.out.println("来了老弟~");
    //系统过来.输出.在控制台输出(输出打印的内容)

    Scanner scanner=new Scanner(System.in);
    //把那个扫描控制台的那个人给我叫过来 这个人的名字就是scanner
    int a=scanner.nextInt();
    //你让这个人从控制台读入一个整数并且给了变量a

    Random random=new Random();
    //把那个负责生成随机数的人给我叫过来 这个人的名字是random
    int a=random.nextInt();
    //让这个人给我生成一个随机的整数 给变量a

对象与类

面向对象有什么样的好处呢?
可以仿真的模拟现实生活中的事物,可以实现更加复杂的业务逻辑
淘宝在买东西的时候 查看商品->付款->生成订单->物流信息
如何描述一个坐标呢?
    在面向过程的思想里面
        int x,y;
        int[] point={1,2};
        额外的 如果是一组坐标
        int x1,y1,x2,y2,x3,y3....
        int[][] points={{1,2},{3,4},{5,6}};
        其次对于他们之间的操作 , getDistance(p1,p2) 求两点间的距离,会发现数据和操作是分开的,
        弊端就是不方便统一管理。
    在面向对象的思想里面
        p1=创建一个Point对象并且制定x=1,y=2
        p2=创建一个Point对象并且指定x=3,y=4
        p1.x p1.y
        p1.getDistance(p2) 让p1自己去和p2之间计算距离,好处在于将数据和操作统一起来了
        意味着将点拟人化,该事物的数据和操作就可以统一起来了。

对象是什么?类是什么?

对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。(大白话来讲就是真实存在且具体的事物,由某一个类所描述出来的具体的事物)

具有相同或相似性质的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。(大白话来讲就是类主要用来描述事物,其实是事物的属性用数据来表示,事物的行为用函数来表示)

如果还太懂就记住这句话:类相当于大楼设计图纸,对象就是由该图纸所建成的大楼。

现在我们再来描述一个坐标
目前而言 但凡创建对象 用new关键字
    格式:类名/数据类型 变量名=new 类名();
    如何访问对象中的成员呢 变量名.成员

//属性   x    y

//行为   getDistance()

class Point{//Point类
    double x;//成员变量
    double y;
    public double getDistance(Point other){//成员函数
        return Math.hypot(x-other.x,y-other.y);
    }
}
class Test01{
    public static void main(String[] args){
        Point p1=new Point();
        Point p2=new Point();
        //System.out.println(p1.x);0.0
        //System.out.println(p1.x);0.0
        p1.x=10;
        p1.y=20;
        p2.x=30;
        p2.y=40;
        System.out.println(p1.getDistance(p2));
        System.out.println(p2.getDistance(p1));//两结果是一样的
    }
}

 

从上边两个代码可以看出当我们在创建一个类的时候 其实就是在自定义一个数据类型。
注意:建议一个类一个.java文件 方便类管理(不论是主类还是被调用的类),如果你偏要放在一起,也可以,编译后,会产生两个.class文件;

如果你遇到分开写两个类报错时,看一下你的系统环境变量里是否有ClassPath,有的话删掉,一路确定出来,重启cmd就可以了。这是因为ClassPath会自动调用java自己内部的类,你没导包自然会报错找不到符号。

对象的内存图解①

这里就不画常量池了。只画一下栈,堆,方法区。

不论几个对象,函数只加载一次。

步骤:

1.在堆内存中开辟一个空间并分配地址

2.按照类的描述,在该空间中定义成员变量,并且有默认初始化值

3.加载成员函数进入方法区(只加载一次)

4.对象加载完毕,将空间地址赋值给相应的变量

5.变量(p1/p2)调用成员函数

直接去方法区找该成员函数,将该函数加载进栈内存开始运行。

为了方便区分哪一个对象调用的该成员函数,有this这个关键字段,来区分this主要存的是当前对象的地址

注意:当成员函数在操作空间的时候,先在当前函数的空间里找局部变量,如果没有找到,再去this所指向的堆内存中对象所属空间里去找。

下面来练习一下,对照代码巩固一下对象的内存图解

class Test02{
    /*
    定义一个解决一元二次方程的类
        数据 
            a,b,c,delt
        行为
            isSolved() 判断是否有解
            getRoot1() 获取第一个解
            getRoot2() 获取第二个解
    QuadrationEquation
    */
    public static void main(String[] args){
        QuadrationEquation qe=new QuadrationEquation();
        qe.a=10;
        qe.b=50;
        qe.c=5;
        System.out.println(qe.isSovled());
        System.out.println(qe.getRoot1());
        System.out.println(qe.getRoot2());
    }
}

class QuadrationEquation{
    double a;
    double b;
    double c;
    double delt;
    public boolean isSovled(){
        delt=b*b-4*a*c;
        return delt>=0;
    }
    public double getRoot1(){
        return (-b+Math.sqrt(delt))/(2*a);
    }
    public double getRoot2(){
        return (-b-Math.sqrt(delt))/(2*a);
    }
}

 


 

class Test03{
    /* 
    点类Point
        数据 x横坐标 y纵坐标
        行为 getDistance(Point other) 返回当前点和传入点other之间的距离

    三角形类Triangle
        数据 Point p1,p2,p3
        行为 getArea() 返回当前三角形的面积
             getLength() 返回当前三角形的周长
    */
    public static void main(String[] args){
        Triangle t=new Triangle();
        Point p1=new Point();
        p1.x=0;
        p1.y=10;
        Point p2=new Point();
        p2.x=0;
        p2.y=0;
        Point p3=new Point();
        p3.x=10;
        p3.y=0;
        t.p1=p1;
        t.p2=p2;
        t.p3=p3;
        System.out.println(t.getLength());
        System.out.println(t.getArea());
    }
}
class Point{
    double x;
    double y;
    public double getDistance(Point other){
        return Math.hypot(x-other.x,y-other.y);
    }
}
/*
三角形类Triangle
        数据 Point p1,p2,p3
        行为 getArea() 返回当前三角形的面积
             getLength() 返回当前三角形的周长
*/
class Triangle{
    Point p1;
    Point p2;
    Point p3;
    public double getArea(){
        double side1=p1.getDistance(p2);
        double side2=p1.getDistance(p3);
        double side3=p2.getDistance(p3);
        double s=(side1+side2+side3)/2;
        return Math.sqrt(s*(s-side1)*(s-side2)*(s-side3));
    }
    public double getLength(){
        return p1.getDistance(p2)+p1.getDistance(p3)+p2.getDistance(p3);
    }
}

 

本人也是初学者,下一个博客再继续补充面向对象的知识,关注博主不迷路:https://blog.csdn.net/f1244313823

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值