01_2_Java面向对象(上)

Java面向对象编程

java面向对象学习的三条主线:

  • Java类和类的成员:属性Field、方法Method、构造器Constractor;代码块、内部类
  • 面向对象三大特征:封装性、继承性、多态性、(抽象性)
  • 其他关键字:this、super、static、final、abstract、interface、package、import等

面向对象OOP与面向过程POP对比:

  • 面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。

    ①打开冰箱

    ②抬起大象,放进冰箱

    ③关上冰箱门

  • 面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。

    人{

    ​ 打开(冰箱){

    ​ 冰箱.打开();

    ​ }

    ​ 抬起(大象){

    ​ 大象.进入(冰箱);

    ​ }

    ​ 关闭(冰箱){}

    }

    冰箱{

    ​ 打开(){}

    ​ 关闭(){}

    }

    大象{

    ​ 进入(冰箱){}

    }

1 类和对象

类是对一类事务的描述,是抽象的、概念上的定义

对象是实际的该类事务的每个个体,因此也成为实例(instance)

面向对象设计的重点是类的设计。

类的设计就是类的成员的设计。

  • 属性(field):对应类中的成员变量、域、字段
  • 行为:对应类中的成员方法(method)、函数

①类和对象的使用

  1. 创建类,设计类的成员
  2. 创建类的对象
  3. 通过“对象.属性”或“对象.方法”调用对象的结构
  • 如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的);意味着,如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。

  • 对象内存解析

    • 堆(Heap):存放对象实体
    • 栈(Stack):存储局部变量(方法中的变量都是局部变量)
    • 方法区(Method Area):类信息、常量、静态变量、即时编译器编译后的代码

    1595169161052

②匿名对象

对于不定义对象的句柄,直接调用这个对象的方法。这样的对象就叫做匿名对象。

比如:System.out.println(new Person().shout()) 直接输出新new的对象的方法

​ System.out.println((new Person().name)) 直接输出新new的对象的属性(默认name=null,也可以使用带有参数的构造器进行赋值:System.out.println(new Person(“jiwei”, 24)))也可以输出属性。

③类中属性的使用:

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

1596102060854

  • 相同点:

    • 1 定义变量的格式:数据类型 变量名 = 变量值
    • 2 先声明,后使用
    • 3 变量都有其作用域
  • 不同点:

    • 1 在类中声明的位置不同

      属性:直接定义在类的一对{}内

      局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量

    • 2 关于权限修饰符的不同

      属性:可以在声明属性的时候,指明其权限,使用public、private、缺省、protected等权限修饰符

      局部变量:不可以使用权限修饰符

    • 3 默认初始化值的情况

      属性:根据其类型都有默认初始化值:整型(byte short int long)0、浮点型(float double)0.0、字符型(char)0、引用数据类型(类 数组 接口)null

      局部变量:没有默认初始化值,意味着调用局部变量时一定显示赋值,形参在调用时赋值即可。

    • 4 在内存中加载的位置不同

      属性:加载的到堆空间(非static)

      局部变量:加载到栈空间

成员变量(属性)和局部变量的内存解析:

1596102618731

对象属性的默认初始化值:

1596102745022

④类中方法的使用:

方法描述类应该有的功能。

分类:

无返回值有返回值
无形参void 方法名(){}返回值类型 方法名(){}
有形参void 方法名(形参列表){}返回值类型 方法名(形参列表){}
  • 方法的声明:权限修饰符 返回值类型 方法名(形参列表){

    ​ 方法体}

    • 关于权限修饰符:private 、public 、缺省、 protected

    • 关于返回值类型:有返回值的、没返回值的

      有返回值的:需要return关键字返回指定类型的变量或常量,一定需要返回

      无返回值的:声明时需要使用void来表示,如果用“return”是结束方法的作用

    • 方法名:属于标识符,见名知意

    • 形参列表:方法可以声明0个,1个或多个形参。

return关键字的使用:

  • 方法的使用:可以调用当前类的属性或方法;方法中不可以定义其他的方法

1595230496059

上述案例的代码
package com.atguigu.test;

/**
 * @author:Ven
 * @date:2020/7/20 - 14:14
 * @function:
 */
public class StudentTest01{
    public static void main(String[] args) {
        //声明student类型的数组
        Student01[] students = new Student01[20];
        for (int i = 0; i < students.length; i++) {
            //给数组元素赋值
            students[i] = new Student01();

            //学号1-20
            students[i].number = (i+1);
            //年级:1-6
            students[i].state = (int) (Math.random()*(6-1+1)+1);
            //成绩:0-100
            students[i].score = (int) (Math.random()*(100-0+1));
        }
        //遍历学生数组
        StudentTest01 test01 = new StudentTest01();
        test01.printStuInfo(students);

        System.out.println("********************************");
        //问题1 打印出3年级学生的信息
        test01.searchState(students, 3);

        System.out.println("********************************");

        //问题2 使用冒泡排序按学生成绩排序,并遍历所有学生信息
        test01.sortStuInfo(students);

        //遍历学生信息
        test01.printStuInfo(students);
    }
    //遍历学生数组

    public void printStuInfo(Student01[] student01s){
        //遍历学生信息
        for (int i = 0; i < student01s.length; i++) {
            System.out.println(student01s[i].number+"\t"+student01s[i].score+"\t"+student01s[i].state);
        }
    }

    //打印出3年级学生的信息方法
    public void searchState(Student01[] student01s, int state){
        for (int i = 0; i < student01s.length; i++) {
            if (student01s[i].state==state){
                System.out.println(student01s[i].number+"\t"+student01s[i].score);
            }
        }
    }

    //使用冒泡排序按学生成绩排序,并遍历所有学生信息
    public void sortStuInfo(Student01[] student01){
        for (int i = 0; i < student01.length-1; i++) {
            for (int j = 0; j < student01.length - 1 - i; j++) {
                if (student01[j].score>student01[j+1].score){
                    Student01 temp = student01[j];
                    student01[j] = student01[j+1];
                    student01[j+1] = temp;
                }
            }
        }
    }
}
class Student01{
    int number;//学号
    int state;//年级
    int score;//成绩  
}
上述案例的内存解析

编译完源代码以后,生成一个或多个字节码文件。

我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。

虚拟机栈,即为平时提到的栈结构,我们将局部变量存储到栈结构中。

堆,new出来的结构(比如数组、对象)。对象的属性(非static)

1595265244692

  • 内存解析案例:

1596100164378

1596100151256

⑤方法的重载

定义:同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可

​ “两同一不同”:同一个类、同一个方法名,参数列表不同(参数个数、参数类型)

public class OverLoadTest {
	public static void main(String[] args) {	
		OverLoadTest test = new OverLoadTest();
		test.getSum(1,2);	
	}	
	//如下的4个方法构成了重载
	public void getSum(int i,int j){System.out.println("1");}
	
	public void getSum(double d1,double d2){System.out.println("2");}
	
	public void getSum(String s ,int i){System.out.println("3");}
	
	public void getSum(int i,String s){System.out.println("4");}
	
	//如下的3个方法不能与上述4个方法构成重载
//	public int getSum(int i,int j){return 0;}
	
//	public void getSum(int m,int n){}
	
//	private void getSum(int i,int j){}	
}

⑤可变个数形参

  1. jdk5.0新增特性,允许直接定义能和多个实参相匹配的形参。通常用在与数据库交互的时候!

  2. 具体使用:

    • 格式:方法名(参数的类型名 …参数名)

    • 当调用可变个数参数的方法时,参数个数可以是0个、1个。。。

    • 可变个数形参的方法与本类方法中方法名相同,形参个数不同的方法之间构成重载

    • 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组,不能共存。

    • 可变个数形参必须声明在末尾!并且也只能存在一个可变个数形参。

      public void show (int i , String … strs)

public class MethodArgsTest {
    public static void main(String[] args) {
        MethodArgsTest test = new MethodArgsTest();
        test.show(19);
        test.show("jiWei");
        test.show("jiWei", "sunYan", "liuZiXin");       
    }    
    public void show(int i){
        System.out.println(i);
    }

    public void show(String s){
        System.out.println(s);
    }

    public void show(String...s){
        System.out.println(s);
        for (int i = 0; i < s.length; i++) {
            System.out.println(s[i]);
        }
    }
}

⑥方法参数的值传递机制

  • 关于变量的赋值

    • 如果变量是基本数据类型,此时赋值的是变量所保存的数据值
    • 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值
  • 关于方法的形参的传递机制:值传递

    • 形参:方法定义时,声明的小括号内的参数
    • 实参:方法调用时,实际传递给形参的数据
值传递机制的内存解析
  • 案例1:

1596107321167

  • 案例2:

1596106912867

  • 案例3(!!!!)

1596107901950

  • 案例4(!!!!)

1596108682702

  • 案例5(!!!!)

1596109034789

  • 案例6(!!!)

    1596110016616

⑦递归方法的使用(了解)

需要从内存中方法的入栈出栈进行分析!!

1598621166938

2 OOP特征:封装性

①思想

把该隐藏的隐藏起来,把该暴露的暴露出来。

具体表现为信息的隐藏:

  • 通过将数据声明为私有的private,再提供公共的public方法:**getXxx()setXxx()**实现对属性的操作。
class Animal {
private int legs;// 将属性legs定义为private,只能被Animal类内部访问
public void setLegs(int i) { // 在这里定义方法 eat() 和 move()
if (i != 0 && i != 2 && i != 4) {
System.out.println("Wrong number of legs!");
return; }
legs = i; }
public int getLegs() {
return legs; } }
public class Zoo {
public static void main(String args[]) {
Animal xb = new Animal();
xb.setLegs(4); // xb.setLegs(-1000);
//xb.legs = -1000; // 非法
System.out.println(xb.getLegs());
} }

②权限修饰符

1596113727968

3构造器

①概念

构造器或者成为构造方法

构造器又分为了无参构造器和有参构造器。

系统默认提供一个隐式的无参构造器;也可以自己显式定义多个构造器(有参或无参)

特点:

  • 具有和类相同的名称

  • 不声明返回值:public Person(){}

  • 修饰符有:不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值。

②作用

创建对象;给对象进行初始化!

比如:Order o = new Order(); Person p = new Person(“Peter”,15);

我的理解就是,就是初始化不同类型的对象,有的对象初始有属性,有的初始没有属性。

③代码

案例1:

public class Animal {
    private int legs;
    //无参构造器
    public Animal(){
        //构造器内初始化属性,也就是说初始化对象的时候,默认animal就有4个legs
        legs = 4;
    }
    public void setLegs(int i){
        legs = i;
    }
    public int getLegs(){
        return legs;
    }
}

public class AnimalTest {
    public static void main(String[] args) {
        Animal animal = new Animal();
        System.out.println(animal.getLegs());//4
    }
}

案例2:

public class PersonTest {
    public static void main(String[] args) {

        Person person = new Person();
        System.out.println(person.getAge());//因为在构造器内初始化了age=18
        person.setAge(29);//使用setAge重新设置age = 29
        System.out.println(person.getAge());
        System.out.println(person.getName());//string类型默认值为null
        person.setName("jiwei");
        System.out.println(person.getName());
    }
}


public class Person {
    //私有属性
    private String name;
    private int age;
    //无参构造器,设置age默认值为18
    public Person(){
        age = 18;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge (){
        return age;
    }
}

案例3:有参构造器和无参构造器对比:

//测试类
public class TriAngleTest {
    public static void main(String[] args) {
        //使用无参构造器实例化一个三角形
        TriAngle angle = new TriAngle();
        angle.setBase(5.0);
        angle.setHeight(10.0);
        System.out.println(angle.findArea());
        System.out.println("==============");
        //使用有参构造器实例化一个三角形
        TriAngle angle1 = new TriAngle(6.0, 3.0);
        System.out.println(angle1.findArea());}}
//三角形类
public class TriAngle {
    private double base;//底
    private double height;//高
    //无参构造器
    public TriAngle(){}
    //有参构造器
    public TriAngle(double base, double height){
        this.base = base;
        this.height = height;}
    //get、set方法
    public double getBase() {
        return base;}
    public void setBase(double base) {
        this.base = base; }
    public double getHeight() {
        return height;}
    public void setHeight(double height) {
        this.height = height; }
    /**
     * @Author jiwei
     * @Description //TODO 计算三角形面积
     * @return 三角形的面积
     **/
    public double findArea(){
        return height*base*0.5;}}

④构造器重载

举例:

public class Person { 
private String name;
private int age;
private Date birthDate;
public Person(String n, int a, Date d) {
name = n;
age = a;
birthDate = d; }
public Person(String n, int a) {
name = n;
age = a; }
public Person(String n, Date d) {
name = n;
birthDate = d; }
public Person(String n) {
name = n;
age = 30;
} }

⑤JavaBean

JavaBean指符合如下标准的Java类:

  • 类是公共的
  • 有一个无参的公共的构造器
  • 有属性,且有对应的get、set方法

JavaBean示例:

public class JavaBean {
private String name; // 属性一般定义为private
private int age;
public JavaBean() {
}
public int getAge() {
return age; }
public void setAge(int a) {
age = a; }
public String getName() {
return name; }
public void setName(String n) {
name = n; } }

⑥UML类图

1596116906283

4关键字

①this关键字

它在方法内部使用,即这个方法所属对象的引用;

它在构造器内部使用,表示该构造器正在初始化的对象

this 可以调用类的属性、方法和构造器

1596117170354

②package关键字

package语句作为Java源文件的第一条语句,指明该文件中定义的类所在

的包。(若缺省该语句,则指定为无名包)。它的格式为:

package 顶层包名**.**子包名 ;

举例:

pack1\pack2\PackageTest.java 

package pack1.pack2; //指定类PackageTest属于包pack1.pack2 

public class PackageTest{ 

public void display(){ 

System.out.println("in method display()"); 

} } 

包对应于文件系统的目录,package语句中,用 “.” 来指明包(目录)的层次;

包通常用小写单词标识。通常使用所在公司域名的倒置:com.atguigu.xxx

③import关键字

import语句告诉编译器到哪里去寻找类。

语法格式:

import 包名**.** 类名**;**

5MVC设计模式

1596117725027

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

最佳第六六六人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值