java面向对象详解(一)

数组的内存图

在这里插入图片描述

面向对象

封装、继承、多态

面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节

面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个具有该功能的人,来帮我做事(找一个JDK给我们提供好的 类)

在这里插入图片描述

输出结果,上面面向过程,下面面向对象

在这里插入图片描述

类和对象

环顾周围,你会发现很多对象,比如桌子,椅子,同学,老师等。桌椅属于办公用品,师生都是人类。那么什么是类呢 ? 什么是对象呢 ?

什么是类

: 是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。
现实中,描述—类事物 :
​ **属性 **: 就是该事物的状态信息。

​ **行为 **: 就是该事物能够做什么。
举例:小猫。
​ 属性:名字、体重、年龄、颜色。
​ 行为:走、跑、叫。

什么是对象

对象:是一类事物的具体体现。对象是类的一个实例(对象并不是找个女朋友),必然具备该类事物的属性和行为。

现实中,一类事物的一个实例:—只小猫。

举例:—只小猫。

行为:溜墙根走、蹦蹴的跑、瞄茹叫。

类与对象的关系

类是对—类事物的描述,是抽象的
对象是—类事物的实例,是具体的
类是对象的模板,对象是类的实体

在这里插入图片描述

类的定义

事物与类的对比
现实世界的—类事物:
属性:事物的状态信息。
行为:事物能够做什么。
Java中用class描述事物也是如此:
成员变量:对应事物的属性
成员方法:对应事物的行为

/*
*定义一个类,用来模拟“学生”。其中就有两个组成部分
* 属性(是什么)
*   姓名
*   年龄
* 行为(能做什么)
*   吃饭
*   睡觉
*   学习
*   
* 对应到java类中
* 成员变量(属性):
*   String name // 姓名
*   int age     //年龄
* 成员方法(行为):
*   public void eat(){}    //吃饭
*   public void sleep(){}  //睡觉
*   public void study(){}  //学习
*   
*  注意事项
*  1.成员变量是直接定义在类中的,在方法外边
*  2.成员方法不要写static关键字
*   
*/
public class Student {
    //成员变量
    String name; // 姓名
    int age;     //年龄
    //成员方法  
    public void eat(){
        System.out.println("吃饭饭");
    }
    public void sleep(){
        System.out.println("睡觉觉");
    }
    public void study(){
        System.out.println("学习!");
    }
}
类的使用
 通常情况下,一个类不能直接使用,需要根据类创建一个对象,才能使用
*
* 1.导包:也就是指出需要使用的类,在什么位置
* import 包名称.类名称
* import com.java.okDay01.Student
* 对于和当前类属于同一包的情况下,可以省略导包语句不写
*
* 2.创建,格式:
* 类名称 对象名 = new 类名称()
* Student stu = new Student()
*
* 3.使用,分为两种情况
* 使用成员变量:对象名.成员变量名
* 使用成员方法:对象名.成员方法名(参数)
* (也就是,想用谁,就用对象名点儿谁)
*
* 注意事项:
* 如果成员变量没有进行赋值,那么将会有一个默认值,int 0,String null
public class demo02Student {
    public static void main(String[] args) {
//     1.导包
//     我需要使用的Student类,和我自己当前文件在同一个包下,所以省略导包语句不写

//     2.创建,格式:
//     类名称 对象名 = new 类名称()
        Student stu = new Student();
//      3.使用其中的成员变量,格式:
//        对象名.成员变量名
        System.out.println(stu.name);// null
        System.out.println(stu.age); // 0

//        改变对象中的成员变量值的内容
//        将右侧的字符串,赋值给stu对象中的成员变量
        stu.name = "韩寒";
        stu.age = 25;
        System.out.println(stu.name);// 韩寒
        System.out.println(stu.age); // 25

//        4.使用对象的成员方法,格式:
//        对象名.成员方法()
        stu.eat();   //吃饭饭
        stu.sleep(); //睡觉觉
        stu.study(); //学习!

    }
}
单一对象

在这里插入图片描述

多个对象指向同一引用

在这里插入图片描述

对象作为参数

在这里插入图片描述

对象类型作为返回值

在这里插入图片描述

局部变量和成员变量

1、定义的位置不一样【重点】

局部变量:在方法内部

成员变量:在方法外部,直接写在类中

2、作用范围不一样【重点】

局部变量:只有在方法中才可以使用,出来方法就不能再用

成员变量:整个类都可以通用

3、默认值不一样【重点】

局部变量:没有默认值,如果想使用,必须手动赋值

成员变量:如果没有赋值,会有默认值,规则和数组一样

4、内存位置不一样(了解)

局部变量:栈内存

成员变量:堆内存

5、生命周期不一样(了解)

局部变量:随着方法进栈而诞生,方法出栈而消失

成员变量:随着对象创建而诞生,对象被垃圾回收而消失

封装性

封装性在JAVA中的提现:

1、方法就是一种封装

2、关键字private也是一种封装

封装就是将一些信息细节隐藏起来,对于外界不可见

public class Demo82Method {
	public static void main(String[]args) {
		int[]array = {515252010ej};
		int max = getMax(array);
		system.out.printin("最天值:- + max);
    }
		//给我一个数组,我换给你一个最大值
	public static int getMax(int[] array) {
		int max = array[0];
		for (int i = 1;i < array. length; i++) {
		if (array[i] > max) i
			max =array[i];
		}
	}
		return max;
}

/*
间题描述;定义Person的年龄时,无法阻止不合理的数值被设置进来。
解决方案,用private关键字将需要保护的成员变量进行修饰。
一旦使用了private进行修饰,那么本类当中仍然可以随意访问。

但是超出了本类范围之外就不能再直接访间了。
间接访问private成员变量,就是定义一对儿Getter/Setter方法

必须叫setXxcx或者是getXxx命名规刚。

对子Getter来说,不能有参数,返回值类型和成员变量对应;
对子setter来说,不能有返回值,参数类型和成员变量对应。

对于基本类型的boolean值,Getter方法一定写成isXxx的形式,而setXxx规则不变
*/

this关键字
/*
当方法的局部变量和类的成员变量重名的时候,根据*就近原则”,优先使用局部变量。
如果需要访问本类当中的成员变量,需要使用格式:
this.成员变量名
* /

构造方法
/*
构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法。
格式:
public 类名称(参数类型 参数名称)
	方法体
}

成员变量、无参构造方法、有参构造方法、Getter/Setter

注意事项;
1.构造方法的名称必须和所在的类名称完全一样,就连大小写也要—样
2.构造方法不要写返回值类型,连void都不写
3,构造方法不能return个具体的返回值
4.如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数、方法体什么事情都不做。
		public Student() {}
5.如果编写了至少一个构造方法,那么编译器将不再赠送
6.构造方法也是可以进行重载的
重载:方法名相同,参数列表不同

*/

标准类
/*
* 一个标准的类同城要拥有下面四个部分:
*
* 1.所有的成员变量都要用private关键字修饰
* 2.为每一个成员变量边写一对儿Getter/Setter
* 3.编写一个无参的构造方法
* 4.编写一个有参的构造方法
*
* 这样标准的类也叫作Java Bean
*
* 快捷键 alt + Ins
* */

public class Student {
    private String name;//姓名
    private int age;//年龄

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Demo01Student {

    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.setName("迪丽热巴");
        stu1.setAge(20);
        System.out.println("姓名" + stu1.getName() + ",年龄" + stu1.getAge());
        System.out.println("==============");

        Student stu2 = new Student("古力娜扎",22);
        System.out.println("姓名" + stu2.getName() + ",年龄" + stu2.getAge());
        stu2.setAge(50);
        System.out.println("姓名" + stu2.getName() + ",年龄" + stu2.getAge());
    }
}
Scanner类
import java.util.Scanner;//  1.导包
/*
* Scanner类的功能:可以实现键盘输入数据,到程序当中
*
* 引用类型的一般使用步骤
*
* 1.导包
* import 包路径.类名称
* 如果需要使用的目标类,和当前类位于同一包下,则可以省略导包语句,不写
*只有java.lang包下的内容不需要导包,其他的都需要import语句
*
* 2.创新
* 类名称 对象名 = new 类名称();
*
* 3.使用
* 对象名.成员方法名()
*
* 获取键盘输入的一个int数字:int num = sc.nextInt();
* 获取键盘输入的一个字符串:String str = sc.next();
* */
public class Demo01Scanner {

    public static void main(String[] args) {
        //2.创建
        //备注:System.in  代表从键盘输入
        Scanner sc = new Scanner(System.in);

        int num = sc.nextInt();
        System.out.println(num);
        //4.获取键盘输入的字符串
        String str = sc.next();
        System.out.println(str);
    }
}

在这里插入图片描述

匿名对象
匿名对象创建和使用
public class Person {
    String name;
    public void showName(){
        System.out.println("我叫:"+ name);
    }
}

/*
* 创建对象的标准格式:
* 类名称 对象名 = new 类名称()
*
* 匿名对象就是只有右边的对象,没有左边的名字和赋值运算符
* new 类名称()
*
* 注意事项:匿名对象只能使用唯一的一次,下次使用不得不再创建一个新对象
* 使用建议:如果确定有一个对象只需要使用唯一的一次,就可以使用匿名对象
* */

public class Anonymous {
    public static void main(String[] args) {
        //左边的one就是对象的名字
        Person one = new Person();
        one.name = "高圆圆";
        one.showName();
        System.out.println("============");
        //匿名对象
        new Person().name = "赵又廷";
        new Person().showName();
    }
}

在这里插入图片描述

匿名对象作为方法的参数和返回值
import java.util.Scanner;

public class Anonymous02 {
    public static void main(String[] args) {
        //普通方式
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();

        //匿名对象方式
        int sum = new Scanner(System.in).nextInt();
        System.out.println("输入的是:"+ sum);

        //使用一般写法传入参数
        Scanner sc01 = new Scanner(System.in);
        methodParam(sc);

        //使用匿名对象来进行传参
        methodParam(new Scanner(System.in));
		
        //使用匿名参数的返回值
        Scanner sc = methodReturn();
        int num01 = sc.nextInt();
        System.out.println("输入的是:" + num01);
    }

    //匿名对象作为参数
    public static void methodParam(Scanner sc){
        int num = sc.nextInt();
        System.out.println("输入的是:" + num);
    }

    //匿名对象作为返回值
    public static Scanner methodReturn(){
//        Scanner sc = new Scanner(System.in);
//        return sc;
        return new Scanner(System.in);
    }
}
static
package Day03Static;

/*
  static关键字
 * 如果一个成员变量使用l static关键字,那么这个变量不在属于自己,而是属于所在的类的多个对象共享一份数据
 */
public class Demo01StaticField {
    public static void main(String[] args) {
        Statudent one = new Statudent("郭靖",19);
        one.room = "1011教室";
        System.out.println(one.getName() + one.getAge() + one.room + one.getId());
        Statudent two = new Statudent("黄蓉",16);
        System.out.println(two.getName() + two.getAge() + two.room + two.getId());

    }
}
package Day03Static;

public class Statudent {
    private String name;//姓名
    private int age;//年龄
    static String room;//教室
    private int id;//学号(usrid)
    private static int idCount;//学号计数器(usrid)

    public Statudent() {
    }

    public Statudent(String name, int age) {
        this.name = name;
        this.age = age;
        this.id = ++idCount;
    }

    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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}




package Day03Static;

public class myClass {
    int num;
    static int numStatic;
    public void method() {
        System.out.println("这是一个普通的成员方法");
        //成员方法可以直接访问成员变量
        System.out.println(num);
        //成员方法可以访问静态变量
        System.out.println(numStatic);
    }

    public static void methodStatic() {
        System.out.println("这是一个静态通的成员方法");
        //静态方法可以访问静态变量
        System.out.println(numStatic);
        //静态方法不可以直接访问非静态变量【重点】
       /* System.out.println(num);//错误写法
       * System.out.println(this);//错误写法
       * */
    }
}

package Day03Static;

/*
* 一旦使用static修饰成员方法,那么这就成为了静态方法。 静态方法不属于对象,而是属于类的
*
* 如果没有static关键字,那么必须先创建对象,然后才能通过对象才能使用它
* 如果有static关键字,那么不需要创建对象,直接就能通过类名称来使用它
*
* 无论是成员变量,还是成员方法,如果有了static,都推荐使用类名称进行调用
* 静态变量:类名称.静态方法
* 静态方法:类名称.静态方法
*
* 注意事项:
* 1.静态只能直接访问静态,静态不能直接访问非静态
* 原因:因为在内存中先有的静态,后有的非静态
* “后人知道先人,先人不知道后人”
* 2.静态方法中不能使用 this
* 原因: this 代表当前对象,通过谁调用的方法,谁就是当前对象
* */

public class Demo02StaticMethod {
    public static void main(String[] args) {
        //首先创建对象
        myClass obj = new myClass();
        //然后通过对象使用没有static关键字的内容
        obj.method();

        //对于静态方法来说,可以通过对象名进行调用,也可以直接通过类名称来调用
        obj.methodStatic();//正确,不推荐使用,这种写法在编译后也会被javac翻译称为“类名称.静态方法名”
        myClass.methodStatic();//正确,推荐使用

        //对于本类中的静态方法,可以省略类名称
        myMethod();
        Demo02StaticMethod.myMethod();
    }
    public static void myMethod(){
        System.out.println("自己的方法");
    }
}

static内存图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HPBdOULy-1606110303215)(C:\Users\心中自有天地\AppData\Roaming\Typora\typora-user-images\1600093192802.png)]

静态代码块
/*
 * 静态代码块 ==>>
 * 格式:
 * public class 类名称{
 *   static{
 *       //静态代码块内容
 *   }
 * }
 *
 * 特点:当第一次用到本类时,静态代码块执行唯一的一次
 * 静态的内容总是优先于非静态,所以静态代码块比构造方法优先执行
 *
 * 静态代码块的典型用法:
 * 用来一次性的对静态成员变量进行赋值
 * */

public class Person {
    static{
        System.out.println("静态代码块");
    }
    public Person() {
        System.out.println("构造方法执行");
    }
}


public class Demo04Static {
    public static void main(String[] args) {
        Person one = new Person();
        Person two = new Person();
    }
}

输出:
静态代码块
构造方法执行
构造方法执行

数组Arrays工具类
package Day04;

import java.util.Arrays;
/*
 * java.util.Arrays是一个与数组相关的工具类,里面提供了大量的静态方法,用来实现数组常见的操作
 *
 * public static String toString(数组),将参数数组变成字符串(按照默认格式:【元素1,元素2,元素3...】)
 * public static void sort(数组),按照默认升序(从小到大)对数组元素进行排序
 *
 * 备注:
 * 1.如果是数值,sort默认从小到大
 * 2.如果是字符串,sort默认按照字母升序
 * 3.如果是自定义类型,那么这个自定义的类需要有Comparable或者Comparator接口支持
 * */
public class Demo01Arrays {
    public static void main(String[] args) {
        int[] intArray = {10,20,30};
        //将int[]数组按照默认格式变成字符串
        String inStr = Arrays.toString(intArray);
        System.out.println(inStr);//[10,20,30]

        int[] array1 = {1,5,7,4,2,3,6,9};
        Arrays.sort(array1);
        System.out.println(Arrays.toString(array1));

        String[] array2 = {"ddd","aaa","bbb","ccc"};
        Arrays.sort(array2);
        System.out.println(Arrays.toString(array2));
        
        //将随机字符串倒序排列
        String str = "456kabdirehmxoaz";
        //将字符串 转换成 数组,用sort进行排序,倒着输出
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        for(int i = chars.length - 1;i >= 0;i-- ){
            System.out.print(chars[i])
        }
    }
}

输出:
[10, 20, 30]
[1, 2, 3, 4, 5, 6, 7, 9]
[aaa, bbb, ccc, ddd]
zxromkihedbaa654
数学相关工具类Math
/*
* java.util.Math类是数学相关的工具类,里面提供各类大量的静态方法,完成与数学运算相关的操作
* 
* public static doublu abs(double num):获取绝对值
* public static dopuble ceil(double num):向上取整
* public static double floor(double num):向下取整
* public static double round(doouble num):四舍五入
* Math.PI():π的近似值
* */
继承和抽象类

面向对象三大特征:封装、继承、多态

继承是多态的前提,如果没有继承,就没有多态

继承(共性抽取)

继承关系中的特点:

1.子类可以拥有父类的“内容”

2.子类可以拥有自己专属的特点

/*
*在继承关系中,“子类就是一个父类”,也就是说,子类可以被当做父类看待
* 例:父类是员工,子类是讲师,那么“讲师就是一个员工”,关系;is-a
*
* 定义父类的格式:(一个普通的类定义)
* public class 父类名称{
*   //....代码
* }
*
* 定义子类的格式:
* public class 子类名称 extends 父类名称{
*   //...代码
* }
*
* */
public class Demo01Extends {
    public static void main(String[] args) {
        //创建子类对象
        Teacher teacher = new Teacher();
        //子类中什么都没写,也是会继承来u自父类的方法,调用父类方法
        teacher.method();
        Assisant assisant = new Assisant();
        assisant.method();
    }
}
/* 定义父类 */
public class Employee {
    public void method() {
        System.out.println("父类放法执行");
    }
}
/* 定义子类 */
public class Teacher extends Employee {

}
/* 定义另一个子类 */
public class Assisant extends Employee {

}
输出:
父类放法执行
父类放法执行

/*
* 局部变量              直接写
* 本类的成员变量        this.成员变量名
* 父类的成员变量        super.成员变量名
* */
public class Demo03ExtendsField {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.method();
    }
}
/* 定义父类 */
public class Fu {
    int num = 10;
}
/* 定义子类 */
public class Zi extends Fu {
    int num = 20;
    public void method(){
        System.out.println("重名时候优先输出num:" + num);
        System.out.println("重名时候本类this.num:" + this.num);
        System.out.println("重名时候输出父类super.num:" + super.num);//父类的成员变量
    }
}
输出:
重名时候优先输出num:20
重名时候本类this.num:20
重名时候输出父类super.num:10

/*
* 在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问方式有两种
*
* 直接 通过 子类对象 访问成员变量
*   等号左边是谁,就优先用谁,没有就向上(父类)找
* 简介 通过 成员方法 访问成员变量
*    方法属于谁,优先用谁,没有向上(父类)找
* */
public class Demo01WxtendsField {
    public static void main(String[] args) {
        //创建父类对象
        Fu fu = new Fu();
        //只能使用父类的东西,没有子类任何内容
        System.out.println(fu.numFu);

        Zi zi = new Zi();
        System.out.println(zi.numFu);
        System.out.println(zi.numZi);
        System.out.println("=================");

        //等号左边是谁,就优先用谁
        System.out.println(zi.num);//优先子类

        //这个方法是子类的,优先用子类的,没有再向父类找
        zi.methodZi();
        //这个方法是 父类中定义的,
        zi.methodFu();
	}
}
/* 定义父类 */
public class Fu {
    int numFu = 10;
    int num = 100;
    public void methodFu() {
        System.out.println("父类输出:" + num);

    }
}
/* 定义子类 */
public class Zi extends Fu {
    int numZi = 20;
    int num = 200;

    public void methodZi() {
        //本类中有 num 优先使用本类
        System.out.println("子类输出:" + num);
    }
}
输出:
10
10
20
=================
200
子类输出:200
父类输出:100
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值