Java面向对象(上)

Java面向对象(上) (Obeject Oriented Programming)

面向对象的三条主线

  1. Java类及类的成员:属性、方法、构造器;代码块、内部类
  2. 面向对象的三大特征:封装、继承、多态
  3. 其它关键字:this,super,static,final,abstract,interface,package,import

1.类和对象的基本概念

  • 类是抽象的,是概念上的定义
  • 对象是类的实例(instance)
  • 面向对象的程序设计的重点是类的设计
  • 设计类,就是设计类的成员

属性 = 成员变量(field) = 域、字段
方法 = 成员方法(method)= 函数

2.类和对象的使用

  1. 创建类、设计类的成员(属性和方法)
  2. 创建类的对象
  3. 通过对象.属性对象.方法调用对象的结构
//测试类
public class PersonTest{
    public static void main(String[] args) {
        //1.创建类的对象 = 类的实例化
        Person man = new Person();
        //2.调用对象的属性"对象名.属性"
        man.name = "Tom";
        man.age = 20;
        man.isMale = true;
        System.out.println(man.name+" "+man.age+" "+man.isMale);
        //3.调用对象的方法"对象名.方法"
        man.eat();
        man.talk("English");
    }
    
}

class Person{
    //属性(成员变量)
    String name;
    int age;
    boolean isMale;
    //行为(方法)
    public void eat(){
        System.out.println("人可以吃饭");
    }
    public void talk(String language){
        System.out.println("人的语言是"+language);
    }
}
  • 对象名(指针)存储在栈(stack)空间中
  • 对象是存储在堆(heap)空间中,包括对象的成员变量

3.属性和局部变量

3.1 声明位置

属性:直接定义在类的{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内内部的变量

3.2 权限修饰符不同

属性:可以在声明属性时,指明其权限,使用权限修饰符:private,public,缺省,protected(封装性)
局部变量:没有修饰符

3.3 默认初始化值

属性:类的属性,根据其类型,都有默认的初始化值
整形(byte,short,int,long):0
浮点型(float,double):0.0
字符(char):0(或’\u0000’)
布尔类型(boolean):false

引用数据类型(数组、类、接口)null

局部变量:没有初始化赋值

3.4 内存中加载的位置

属性:加载到堆中(heap)(非static)
局部变量:加载到栈中(stack)

4.方法

方法的声明:权限修饰符+返回值类型+方法名(形参列表)
private,public,protected,缺省

public String whatNation(String nation){
    String whatnation = "国籍是"+nation;
    return whatnation;
}

方法的使用中,可以调用当前类中的属性或方法

4. 对象数组

定义了一个Student类

class Student{
    int number; //学号
    int state;  //年级
    int score;  //成绩

    public String info(){
        return "学号 "+number+" 年级"+state+" 成绩 "+score;
    }
}

下面在StudentTest类中创建对象数组

public class StudentTest{
    public static void main(String[] args){
        Student[] stus = new Student[20];
        for(int i = 0;i<stus.length;++i){
            //给对象数组中元素赋值,创建一个对象,把指针赋给它
            stus[i] = new Student();
            //给Student类型的对象赋值,即给对象的属性赋值
            stus[i].number = i+1;
        }
    }
}

Students[] stus = new Student[20];
这条语句执行完,栈中有stus,stus的值是对象数组的地址,
对象数组存储在堆中,当前对象数组的每个元素stus[i] = null

stu[i] = new Students();
执行这条语句后,数组元素变为对象的地址,对象是在堆中的另一片存储空间中

注意:类中的属性如果是引用类型变量,记得new创建对象,否则就是空指针,有2种方法

  1. 定义属性的时候new
  2. 在构造器中new

5.万事万物皆对象的简单理解

  1. 在Java语言范畴中,我们将功能、结构封装到类中,通过类的实例化,来调用具体的功能结构
  2. Java和前段HTML、后端数据交互时,前后端的结构在Java层面交互时,都体现为类、对象
  • 例如数据库中表格中的一条记录可以视为一个对象

6.方法的几个知识点

6.1 方法的重载(overload)

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

  • 两同、一不同:同类,同名,参数列表不同
  • 例如Arrays中重载的sort()/binarysearch(),针对不同数据类型
  • 和返回类型、形参名、修饰符、方法体无关
public class OverloadTest{
    //两个方法同名,在同一个类中,但是参数列表不同
    public int getMax(int i,int j){
    }
    public double getMax(double i,double j){
    }
}

6.2可变形参个数的方法

  • 格式:例如public void show(int number1, double number2, String … str),String可以替换成其他的数据类型
    在使用方法的时候可以输入可变个数的字符串,但必须都是字符串(…前面指定的数据类型)
  • 可变个数形参只能在形参列表的末尾,且只能有1个
//可变个数形参的方法
public class MethodArgsTest{
    public static void main(String[] args) {
        MethodArgs test = new MethodArgs();
        test.show("hello","world","frank");
        
        test.show(new String[]{"hello","world","frank"});
    }
}

class MethodArgs{
    void show(String ... str){      //用String... 表示可变个数形参,str可以理解成字符串数组的首地址,访问也是照常访问
        System.out.println("使用可变个数形参的方法");
        for(int i = 0;i<str.length;++i){
            System.out.println(str[i]);
        }
    }
    
    void showArray(String[] str){   //这两个方法不能重名,即不能重载,两者本质上是等价的
        System.out.println("使用数组来传递参数");
        for(int i=  0;i<str.length;++i){
            System.out.println(str[i]);
        }
    }
}

6.3 值传递机制(传值和传地址)

  1. 对于基本数据类型,方法是传值
  2. 对于引用数据类型,方法是传地址(毕竟引用数据类型就是指针)
    想在原来的数据上做修改,就必须和地址(指针、引用)相关
  • 注意:Java和C不一样的是没有显式指针了(这保证了Java的安全性)
    如果在main函数中定义了int a, 是无法获取a的地址的

下面是交换功能的两种情况,体会一下

public class ValueTransferTest02 {
    public static void main(String[] args) {
        Data data = new Data();
        data.a = 10;
        data.b = 30;
        data.swap(data);    //传递引用数据类型
        System.out.println("a = "+data.a+" b = "+data.b);
        
    }
}

class Data{
    int a;
    int b; 
    void swap(Data data){
        int temp;
        temp = data.a;
        data.a = data.b;
        data.b = temp;
    }
}
//方法的参数传递机制、
//传值还是传地址
public class ValueTransferTest {
    public static void main(String[] args) {
        int [] array = new int[]{2,4,1,3,5,-1};

        System.out.println("排序前");
        for(int i = 0;i<array.length;++i){
            System.out.print(array[i]+" ");
        }

        System.out.println("\n排序后");
        new Array().selectSort(array);
        for(int i = 0;i<array.length;++i){
        System.out.print(array[i]+" ");
        }
    }
    
}

class Array{
    void selectSort(int []array){
        for(int i = 0;i<array.length;++i){
            int k = i;
            for(int j = i+1;j<array.length;++j){
                if(array[j]<array[k]){
                    k = j;
                }
            }
            if(k!=i){
                swap(array,k,i);
            }
        }
    }

    //要实现交换的功能,需要传递地址,也就是这里的array
    //如果不是数组的话,就要传递对象
    //总之实现交换,需要地址
    void swap(int[] array,int i,int j){
        int temp;
        temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

7. 封装性

高内聚,低耦合

  • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
  • 低耦合:仅对外暴露少量的方法用于使用

7.1问题的引入

当我们创建一个类的对象创建一个对象后,可以通过"对象.属性"的方式,对属性进行赋值。这样的赋值只受到数据类型的限制,在实际情况中很有可能是非法的。因此我们需要将属性的权限改为private,这样只能通过方法对属性进行修改

  • 属性的隐藏(封装性)

7.2封装性的体现

  1. 将类的属性私有化(private),提供公共的(public)方法来设置(setLegs)和获取(getLegs)属性
  2. 不对外暴露的私有方法
  3. 单例模式
class Animal{
    private legs;

    //设置属性
    public void setLegs(int legNumber){     //set方法有形参,没有返回值
        if(legNumber<0){
            legs = 0;
        }else{
            legs = legNumber;
        }
    }

    //获取属性
    public int getLegs(){       //get方法没有形参,有返回值
        return legs;
    }
}

setXxx()和getXxx()要熟练掌握

7.3权限修饰符

  1. 4种权限修饰符(从小到大):privte,缺省,protected,public
修饰符类内部同一个包不同包的子类同一个工程
privateYes
缺省YesYes
protectedYesYesYes
publicYesYesYesYes
  1. 4种权限可以用来修饰 类、类的内部结构:属性、方法、构造器、内部类
  • 用来修饰只能用public或者缺省

简单总结:Java的4种权限修饰来修饰类和类的内部结构,体现类和类的内部结构的可见性的大小

8.构造器(constructor)

类的结构之三:构造器(或构造方法)

8.1 构造器的作用

  1. 创建类的对象:new + 构造器
  • 如果没有定义构造器,系统默认提供一个空参的构造器
Person p = new Person();    //默认提供的空参构造器
  1. 初始化对象的属性
Person p = new Person("Tom");       //这句在测试类的main方法中
class Person {
    String name;
    int age;
   
    //构造器格式 = 修饰符+类名(形参列表){}
    public Person() {
        System.out.println("你调用了自定义的构造器");
    }
    public Person(String n){
        System.out.println("你调用了自定义的构造器,并且初始化了对象的属性");
        name = n;
    }
}

8.2 构造器的格式

修饰符+类名(形参列表){}
public Person(String name){
//操作
}

  • 一个类中的多个构造器构成重载(同名、同类、形参列表不同)
  • 一旦我们显式的定义了一个类的构造器之后,系统就不再提供默认的空参构造器
  • 定义一个类一般都是写的顺序是:属性、构造器、方法
  • 默认构造器的权限和类的权限是相同的

9.JavaBean

JavaBean是一种Java语言写成的可重用组件

所谓JavaBean是符合以下条件的类

  1. 类是公共的(public)
  2. 有一个无参的公共的构造器
  3. 有属性,且有对应的set,get方法

JavaBean在后续数据库等的学习中会发挥作用

10.UML类图

要求会看UML类图
image.png

11.关键字 this

this可以理解成当前对象或当前正在创建的对象(构造器中的就是正在创建的对象)

  1. this 可以用来修饰、调用:属性、方法、构造器
  2. 可以用"this.属性"和"this.方法"来调用当前对象属性或方法,但是通常省略this
  3. 特殊的,如果(方法中或构造器中)形参和属性重名了,需要使用 “this.属性”
//this修饰属性
class Person{
    private String name;

    public Person(String name){
        this.name = name;       //this修饰属性
    }
    public void eat(){
        System.out.println("吃饭");
    }
}
  • 在一个构造器中使用this调用其他构造器———— this.Person(形参列表)
  • 规定:使用this(形参列表)调用其他的构造器,必须在当前构造器的首行
//this调用构造器
class Person{
    private String name;

    public Person(){
        this.eat();
        //Person初始化需要40行代码
    }

    public Person(String name){
        this();                 //使用this调用构造器
        this.name = name;
    }

    public Person(String name,int age){
        this(age);              //使用this调用构造器
        this.name = name;
    }

    public void eat(){
        System.out.println("吃饭");
    }
}

12.package 关键字

package 包

  1. 方便项目中类的管理,提供包的概念
  2. 使用package声明类或接口所属的类,声明在源文件的首行,表明当前源文件所属的包,例如:package com.atguigu.exer1
  3. 包,属于标识符,遵循标识符的命名规则,全部小写,见名知意
  4. 每"."一次就代表一层文件目录
  • 补充:
  • 同一个包下不能定义同名的类、接口
  • 不同的包下能定义同名的类、接口

JDK中主要的包
image.png

13.MVC设计模式

View 视图 Controller 控制器 Module 模型
image.png

14. import 关键字

import:导入

  1. 在源文件中显式地导入指定包下的类和接口
import java.util.*;
  1. 声明在包的声明和类的声明之间
  2. 如果使用的类或接口时java.lang包下定义的,那么可以省略import,java.lang的意思是language,是Java的核心包。例如String、System就是在这个包下
  3. 如果类或者接口在同一个包下,也不需要import
  4. 如果在源文件中使用了不同包下同名的类,那么必须至少有一个类用全类名的方式显示
//假设这个类在当前包下
Account acc0 = new Account();
//全类名的方式显示
com.atguigu.exer3.Account acc = new com.atguigu.exer3.Account();
  1. 使用"xxx.*"表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍然需要显式地导入
  2. “import static +package” 导入指定类或接口中的静态结构:属性或方法
  • 注意这里import的落脚点是属性或方法,而没有static的import的落脚点是类或接口
import static java.lang.System.*;
//main方法中
//out是静态的(static)
out.println("Hello");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值