java面向对象编程(一)

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


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

二者都是一种思想,面向对象是相对于面向过程而言的。
面向过程(Object Oriented Programming,强调的是功能行为,以函数为最小单位,强调每个功能的实现步骤。
面向对象(
Procedure Oriented Programming
),将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,强调用对象去调用方法
 
 
面向对象三大特性:
  1. 封装(Encapsulation)
  2. 继承(Inheritance)
  3. 多态(Polymorphism)
 
面向对象中两个重点---类和对象

类(Class)和对象(Object)是面向对象的核心概念。
类是对一类事物的描述,是抽象的、概念上的定义
对象是实际存在的该类事物的每个个体,因而也称为实例(instance)

 

 常见的类的成员有:

  1. 属性:对应类中的成员变量 。 属性 = 成员变量 = Field  =(域、字段)
  2. 行为:对应类中的成员方法 。 (成员)方法 = 函数 = Method
  3. 创建类的对象 = 类的实例化 = 实例化类

理解“万事万物皆对象”:

  1. 在java语言范畴中,我们都将功能、结构等封装到类中,通过类的实体化,来调用具体的功能结构。
  2. 涉及到java语言与前端HTML、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类。对象 
 
类的语法格式:
修饰符 class 类名 {
属性声明;
方法声明; }
说明:修饰符public:类可以被任意访问
类的正文要用{ }括起来
public class Person{
private int age ; //声明私有变量 age
public void showAge(int i) { //声明方法showAge( )
age = i; 
   } 
}
举例—类

 

对象的创建和使用

创建对象语法: 类名 对象名 = new 类名();

使用“对象名.对象成员”的方式访问对象成员(包括属性和方法)。

/*
1、创建类,设计类的成员
2、创建类的对象
3、通过“对象.属性”、“对象.方法”调用对象的结构

4、如果创建了一个类的多个对象,则每个对象都独立拥有一套类的属性(非static的)
 意味着:如果我们修改一个对象的属性a,则不影响另外一个属性a的值
 */
public class OopDemo1 {
    public static void main(String[] args) {
        //创建Person类的对象
        Person p1 = new Person();

        //调用对象的结构:属性、方法
        //调用属性:“对象.属性”
        p1.name = "女驸马";
        p1.age = 18;
        p1.isMale = false;


        //调用方法:“对象.方法”
        p1.eat();
        p1.sleep();
        p1.talk("chinese");

        //创建第二个对象
        Person p2 = new Person();
        System.out.println(p2.name);//null,与p1不同


        //创建第三个对象
        Person p3 = p1;
        //将p1变量保存的对象地址值赋给了p3,导致p1与p3指向了堆空间的同一个对象实体
        System.out.println(p3.name);//女驸马
    }
}

class Person{
    //属性
    String name;
    int age;
    boolean isMale;

    //方法
    public void eat(){
        System.out.println("人可以吃饭");
    }

    public  void sleep(){
        System.out.println("人可以睡觉");
    }

    public  void talk(String language){
        System.out.println("人可以说话,用的是:" + language);
    }
}
对象的创建与使用

 

类的访问机制


 

  1. 在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。(例外:static方法访问非static,编译不通过。)
  2. 在不同类中的访问机制:先创建要访问类的对象,再用对象访问类中定义的成员。

 

对象的内存解析

 

 

 

 

匿名对象:


我们创建的对象,没有显式的赋给一个变量名,即为匿名对象

特征:匿名对象只能使用一次。

 

 

类中属性(field)的使用


属性语法格式:
修饰符 数据类型 属性名 = 初始化值 ;
举例:
public class Person{
private int age; //声明private变量 age
public String name = “Lila”; //声明public变量 name
}
  1. 说明1: 修饰符:常用的权限修饰符有:private、缺省、protected、public;其他修饰符:static、final (暂不考虑)
  2. 说明2:数据类型: 任何基本数据类型(如int、Boolean) 或 任何引用数据类型。
  3. 说明3:属性名:属于标识符,符合命名规则和规范即可。

 

变量的分类:成员变量与局部变量。


 

  1. 在方法体外,类体内声明的变量称为成员变量。
  2. 在方法体内部声明的变量称为局部变量。

 

属性(成员变量)与局部变量的区别

 

public class OopDemo2 {
    public static void main(String[] args) {
        User u1 = new User();
        System.out.println(u1.name);
        System.out.println(u1.age);
        System.out.println(u1.isMale);

        u1.talk("韩语");
        u1.eat();
    }
}

class User{
    //属性
    String name;
    int age;
    boolean isMale;

    public void talk(String language){//language:形参,也是局部变量
        System.out.println(language);
    }
    public void eat(){
        String food = "大米";//局部变量
        System.out.println("南方人喜欢吃:" + food);
    }
}
属性(成员变量)与局部变量

 

成员变量与局部变量的内存位置

 

 

类中方法的声明与使用:


方法的定义:
  1. 描述类应该具有的功能
  2. 将功能封装为方法的目的是,可以实现代码重用,简化代码
  3. Java里的方法不能独立存在,所有的方法必须定义在类里。
方法的声明格式:
 权限修饰符  返回值类型  方法名(参数类型 形参1,参数类型 形参2,……){
    方法体
return 返回值; }

其中权限修饰符:public,缺省,private, protected等。

返回值类型:有返回值  VS 没有返回值

  1. 如果有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量
  2. 如果方法内没有返回值:则方法声明时,使用void来表示,通常,没有返回值的方法就不用returrn,但是,如果使用的话,只能用“return”表示结束方法的意思。
  • 方法名:属于标识符。命名时遵循标识符命名规则与规范。、
  • 形参列表:可以包含零个,一个或多个参数。多个参数时,中间用“,”隔开。
  • 方法体:方法功能的体现。
  • 返回值:方法在执行完毕后返还给调用它的程序的数据。
  • return关键字的使用:使用范围:在方法体内。作用:a.结束方法。  b.对于有返回值类型的方法,使用“return  数据”方法返回所要的数据。return后面不能跟执行语句。
 
方法的使用中,可以调用当前类的属性或方法,特殊的:方法A中又调用了方法A,叫做递归方法
方法中只能调用方法或属性,不可以在方法内部定义方法
 
方法的分类:按照是否有形参及返回值

 

/* 4. 对象数组题目:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息

提示:
1) 生成随机数:Math.random(),返回值类型double;  
2) 四舍五入取整:Math.round(double d),返回值类型long。
 */
public class StudentTest1 {
    public static void main(String[] args) {
        
        //声明Student类型的数组
        Student1[] stus = new Student1[20];  
        
        for(int i = 0;i < stus.length;i++){
            //给数组元素赋值
            stus[i] = new Student1();
            //给Student对象的属性赋值
            stus[i].number = (i + 1);
            //年级:[1,6]
            stus[i].state = (int)(Math.random() * (6 - 1 + 1) + 1);
            //成绩:[0,100]
            stus[i].score = (int)(Math.random() * (100 - 0 + 1));
        }
        
        StudentTest1 test = new StudentTest1();
        
        //遍历学生数组
        test.print(stus);
        
        System.out.println("********************");
        
        //问题一:打印出3年级(state值为3)的学生信息。
        test.searchState(stus, 3);
        
        System.out.println("********************");
        
        //问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
        test.sort(stus);
        
        //遍历学生数组
        test.print(stus);
        
    }
    
    //遍历Student1[]数组的操作
    public void print(Student1[] stus){
        for(int i = 0;i <stus.length;i++){
            System.out.println(stus[i].info());
        }
    }
    
//查找Student数组中指定年级的学生信息
    public void searchState(Student1[] stus,int state){
        for(int i = 0;i <stus.length;i++){
            if(stus[i].state == state){
                System.out.println(stus[i].info());
            }
        }
    }
    

//给Student1数组排序
    public void sort(Student1[] stus){
        for(int i = 0;i < stus.length - 1;i++){
            for(int j = 0;j < stus.length - 1 - i;j++){
                if(stus[j].score > stus[j + 1].score){
//如果需要换序,交换的是数组的元素:Student对象!!!
                    Student1 temp = stus[j];
                    stus[j] = stus[j + 1];
                    stus[j + 1] = temp;
                }
            }
        }
    }
    
    
}

class Student1{
    int number;//学号
    int state;//年级
    int score;//成绩
    
    //显示学生信息的方法
    public String info(){
        return "学号:" + number + ",年级:" + state + ",成绩:" + score;
    }
    
}
对象数组练习题

 

 

 

方法的重载(overload)


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

方法重载的特点:两同一不同:同一个类、方法名。参数列表不同,参数个数不同、参数类型不同。

  1. 与返回值无关,只看方法名和参数列表,且参数列表必须不同。
  2. 在调用的时候,Java虚拟机通过参数列表的不同来区分同名的方法
  3. 判断是否为重载:跟方法的权修饰符、返回值类型、形参变量名、方法体都没有关系。
int a = 18;
        int b = 19;
        int c = 20;
   
        //求a+b的和
        int sum1 = sumNum(a, b);
        System.out.println(sum1);

        //求a+b+c的和
        int sum2 = sumNum(a, b, c);
        System.out.println(sum2);
方法重载的实例

 

 可变个数的形参


 可变个数的形参的方法允许直接定义能和多个实参相匹配的形参。JDK5.0新增的内容。

  1. 可变形参的格式:数据类型  ...  变量名
  2. 可变形参:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
  3. 可变个数形参的方法与同名的方法之间,彼此构成重载
  4. 可变形参必须要写在末尾,在一个方法的形参位置,最多只能声明一个可变个数形参。

 
方法参数的值传递机制

方法,必须由其所在类或对象调用才有意义。若方法含有参数:
形参:方法声明时的参数
实参:方法调用时实际传给形参的参数值
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
 
 
递归方法

递归方法:一个方法体内调用它自身。
方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
public class function01 {
    public static void main(String[] args) {
        function01 f = new function01();
        System.out.println(f.getSum(100));
    }
    //递归方法
    //计算1-100所有的数之和
    public int getSum(int n){
        if (n == 1){
            return 1;
        }else{
            return n + getSum(n-1);
        }
    }
}
递归方法实例—计算1-100所有的数之和

 

 封装与隐藏(封装性)
一、封装性的体现:
  1、我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获(getXxx)和设置(setXxx)此属性的值。
  2、不对外暴露的私有的方法 。
  3、单例模式(将构造器私有化了)……
二、封装性的体现,需要权限修饰符来配合。

1. Java规定的4种权限(从小到大排列):private、缺省、protected 、public

2. 4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类。
3. 具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类。
     修饰类的话,只能使用:缺省、public

 

总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。
 
 
构造器

类的结构之三:构造器(或构造方法、constructor)的使用。

public class Animal {
private int legs;
// 构造器
public Animal() {
legs = 4;
} 
public void setLegs(int i) {
legs = i; }
public int getLegs() {
return legs; } }
构造器举例

一、构造器的作用:

   1.创建对象
   2.初始化对象的信息

二、说明:
   1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
   2.定义构造器的格式:权限修饰符 类名(形参列表){}
   3.一个类中定义的多个构造器,彼此构成重载。

 //构造器一般用来创建对象的同时初始化对象。如
class Person{
String name;
int age;
public Person(String n , int a){ name=n; age=a;}
}
//构造器重载使得对象的创建更加灵活,方便创建各种不同的对象。

构造器重载举例:
public class Person{
public Person(String name, int age, Date d) {this(name,age);…}
public Person(String name, int age) {…}
public Person(String name, Date d) {…}
public Person(){…}
} 
构造器重载,参数列表必须不同
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;
} }
构造器重载举例

   4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
   5.一个类中,至少会有一个构造器。分为两种:隐式无参构造器(系统默认提供)、显式定义一个或多个构造器(无参、有参)。

   6.默认构造器的修饰符与所属类的修饰符一致,父类的构造器不可被子类继承。

 

三、构造器的特征

  1.它具有与类相同的名称
  2.它不声明返回值类型。(与声明为void不同)
  3.不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值。
 
属性赋值过程

属性赋值的先后顺序:
  ① 默认初始化
  ② 显式初始化
  ③ 构造器中初始化
  ④ 通过"对象.方法" 或 "对象.属性"的方式,赋值
    以上操作的先后顺序:① - ② - ③ - ④

 

 

JavaBean(拓展)

JavaBean是一种Java语言写成的可重用组件。
所谓javaBean,是指符合如下标准的Java类:
  1.类是公共的
  2.有一个无参的公共的构造器
  3.有属性,且有对应的get、set方法
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; } }
JavaBean实例

 

 

 
 
 
 

 

posted @ 2021-09-25 21:02  莫尼莫尼  阅读(106)  评论(0编辑  收藏  举报