java---类和对象

2023-10-17 09:11:07 浏览数 (1)

7.1 概述

Java语言是一种面向对象的程序设计语言,而面向对象思想是一种程序设计思想,我们在面向对象思想的指引下, 使用Java语言去设计、开发计算机程序。Java Object Oriented Programming(JavaOOP)

用Java语言来模拟真实的世界,用一系列相关的数据来进行描述的过程。

  • 种类,是一种抽象的概念 (类) class 类名, 类型==种类
  • 具体的事物,是一种具象的概念 (对象) 万事万物都是对象 类名 对象名=new 类名(); Scanner input= new Scanner(System.in)

种类,会规则有哪些属性,种类模板

对象,基于模板创建的,对象是具体的事物,不同的对象的属性值可能不一样,也有可能一样

7.2 语法

代码语言:javascript复制
创建类:
public class 类名{
		属性
		方法
}
创建对象:
 类名  对象名=new 类名();

7.3 属性和方法

属性: 就是定义变量,要看现在定义的类是干嘛用的, people人类,姓名,年龄,身高,性别,国籍,地址.........,属性都于名词相关,属性就用来规定这个种类有哪些名词来描述。

方法:就是定义方法, 方法与动词,动作相关,有关一切动作的代码,比如:input.nextInt(); System.out.println();if() while(); random.nextInt(); 都得放到方法中。

描述: 创建一个人类,有姓名,年龄,性别,身高这四个属性,有睡觉,吃饭,学习这几个功能

代码语言:javascript复制
public class People {
    //定变量 ,  一般情况下类中的属性不需要赋值  成员属性
    String name;
    char gender;
    int age;
    double height;
    //定方法 现在定义方法不需要再加static    成员方法
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
    public void study(){
        System.out.println("学习");
    }
}

类中的属性一般称为成员属性,类中的方法一般称为成员方法(不带static),静态属性和静态方法直接使用类名.属性名或类名.方法名()进行调用 。

7.4对象的使用

.点操作符,对象要调用属性和方法时都要使用点(.) input.nextInt(); random.nextInt(); System.out.println();

代码语言:javascript复制
语法:
对象名.属性名;  //调用属性
对象名.属性名=值; //为属性赋值
System.out.println(对象名.属性名); //使用属性值
对象名.方法名(); //调用

程序从main方法开始执行,main是程序执行的入口,所我们还是要在入口去写代码

代码语言:javascript复制
public class Main {

    public static void main(String[] args) {

        //创建对象

        People zhangpeng =  new People();

        /*

                调用属性

         */

        zhangpeng.name="张鹏";

        zhangpeng.age=25;

        zhangpeng.gender='男';

        zhangpeng.height=179;



        zhangpeng.sleep();

        zhangpeng.eat();

        zhangpeng.study();

        zhangpeng.show();


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


        People xxl =  new People();

        xxl.name="谢兴灵";

        xxl.age=26;

        xxl.gender='男';

        xxl.height=175;

        xxl.sleep();

        xxl.eat();

        xxl.study();

        xxl.show();

    }

}

从以上代码应该有两个问题:

1、类中的方法没有static main为什么能调用

代码语言:javascript复制
public class Main10 {

    public static void main(String[] args) {

        int index = searchNum(search);

        
    }


    public static int searchNum(int search){

        int[] nums=new int[10];

        Random random=new Random();

        for (int i = 0; i < nums.length; i  ) {

            nums[i]=random.nextInt(100) 1;

            System.out.println(nums[i]);

        }

        for (int i = 0; i < nums.length; i  ) {

            if(nums[i]==search){

                return i;

            }

        }

        return -1;

    }

}

结论:这里是对方法进行直接调用,这种调用方式当前的这个方法必须和调用处在同一文件中,因为main方法是静态的,所以直接调用的话这个调用方法也必须是静态的

代码语言:javascript复制
public class Main {

    public static void main(String[] args) {

    
        People zhangpeng =  new People();

      

        zhangpeng.name="张鹏";

        zhangpeng.age=25;

        zhangpeng.gender='男';

        zhangpeng.height=179;



        zhangpeng.sleep();

        zhangpeng.eat();

        zhangpeng.study();

        zhangpeng.show();

    }

}

这里使用的是对象名.方法名()的形式再进行调用,代表的是这个对象在这执行这个方法对应的功能

2、类中的方法使用属性的值时,为什么是main那边设置的结果

对象只要new就会创建一个堆空间,这个空间中存放的就类中的属性和方法

分析图片写出类

代码语言:javascript复制
public class Dog {

    //定变量

    String color;

    String breed;

    String name;

    int age;

    String greder;

    //定方法


    public void eat(){

        System.out.println(name "吃饭");

    }


    public void sleep(){

        System.out.println(name "睡觉");

    }

    public void wang(){

        System.out.println(name "叫");

    }

    public void show(){

        System.out.printf("昵称:%s,品种:%s,颜色:%s,年龄;%d,性别:%s",name,breed,color,age,greder);

    }

}

public class Main1 {

    public static void main(String[] args) {

        Dog dog=new Dog();

        dog.breed="中华田园犬";

        dog.color="黄色";

        dog.name="大黄";

        dog.greder="公";

        dog.age=3;


        dog.eat();

        dog.sleep();

        dog.wang();

        dog.show();

    }

}

问题1:如果在main方法中没有为对象的属性赋值?

如果没赋值,属性有默认值,与数组一样详情参照6.2中的表。因为数组的元素存放的地方是堆,类的成员变量存放的地方也是堆,由此可见,堆中的数据是有默认值的。

问题2: 类中String name;的定义与main方法中的String name定义有何区别?

代码语言:javascript复制
public class Main1 {

public static void main(String[] args) {

  int age;

}

}

public class Dog {

int age;

}

局部变量和全局变量的区别,什么叫局部变量只在定义它的这对大括号中起作用,全局变量,全局都起作用(所谓全局就是在能定义对象的方地),局部变量存放在栈中(方法中定义的变量在栈中),全局变量存放在堆中(类的成员变量在堆中) 局部变量与成员变量(全局变量)同名时,优先使用局部变量

7.5 构造方法

构造方法,每一个类必须有的一个方法,如果没写默认存在,构造方法的名称与类名一样,没有返回值的概念,作用就是用来创建对象或者在创建对象的时候给属性赋值(做初始化用),所以创建对象时都会调用构造方法。

默认构造,没有显示出来,

代码语言:javascript复制
语法:
public   类名(){
}
代码语言:javascript复制
public class Dog {

    public Dog(String color1,String breed1,String name1,int age1,String greder1){

        color=color1;

        breed=breed1;

        name=name1;

        age=age1;

        greder=greder1;

    }

    //定变量

    String color;

    String breed;

    String name;

    int age;

    String greder;

}

public class Main1 {

    public static void main(String[] args) {


        Dog dog=new Dog();//这里报错现在

    }

}

如果显示的把构造方法写出来了以后,默认构造不再起作用,如果以后还想再使用默认的构造怎么办

代码语言:javascript复制
public class Dog {

    //书写规范上有点问题  方法中的变量是局部变量

    public Dog(String color1,String breed1,String name1,int age1,String greder1){

        color=color1;

        breed=breed1;

        name=name1;

        age=age1;

        greder=greder1;

    }


    public Dog(){

        

    }

}

把默认的构造方法再显示的写一遍

7.6 this关键字

this代表对象本身,哪个对象调用这个方法,这个方法中的this就代表调用那个对象。

这里的this是一个对象和dog对象一样,dog对象能做什么事,this就能做什么,只不能一般情况下只是用this来指明现在操作的是成员变量,每个类中都有this,它代表的就是当前这个类的对象

代码语言:javascript复制
public class Dog {


    public Dog(){


    }


    //构造方法的形参变量从书写规范上来说要与成员变量同名

    public Dog(String color,String breed,String name,int age,String greder){

        this.color=color;//当局部变量与成员变量同名的时候优先使用局部变量,这时成员要使用this进行指明

        this.breed=breed;

        this.name=name;

        this.age=age;

        this.greder=greder;

    }

构造方法的形参变量从书写规范上来说要与成员变量同名,当局部变量与成员变量同名的时候优先使用局部变量,这时成员要使用this进行指明

7.7 方法重载

同样的方法名,根据不同的参数去完成不同的功能,怎样样才能形式重载

1、方法重载一定是发生在同一个类文件中

2、方法名必须相同

3、方法的参数必须不一样:

  • 2.1 参数的个数不一样
  • 2.2 同位置参数的类型不一样
代码语言:javascript复制
public void eat(){

        System.out.println(this.name "吃饭");



    }


    public void eat(String food){

        System.out.println(this.name "吃" food);

    }


    public void eat(int n){

        System.out.println(this.name "吃" n "斤肉");

    }


    public void eat(int n,String food){

        System.out.println(this.name "吃" n "斤" food);

    }

    

    public void eat(String food,int n){

        System.out.println("第二个两个参数的方法:" this.name "吃" n "斤" food);

    }

不正确的重载一:

上面两个方法中参数名不一样,但是类型一样,这样无法重载,重载与参数名没关系

不正确的重载二:

方法重载与返回值没有关系

代码语言:javascript复制
如果构造方法进行重构怎么写
反面案例,不要这样去对构造进行重载(方法里面的代码不要这样写)
public Dog(){ }


    public Dog(String name){

        this.name=name;

    }

    public Dog(String name,String breed){

        this.name=name;

        this.breed=breed;

    }


    public Dog(String name,String breed,String color){

        this.name=name;

        this.breed=breed;

        this.color=color;

    }


    public Dog(String name,String breed,String color,int age){

        this.color=color;

        this.breed=breed;

        this.name=name;

        this.age=age;

    }

正确的方式:

代码语言:javascript复制
public Dog(){}


    public Dog(String name){

        this(name,null,null,0,null);

    }

    public Dog(String name,String breed){

        this(name,breed,null,0,null);

    }


    public Dog(String name,String breed,String color){

        this(name,breed,color,0,null);

    }


    public Dog(String name,String breed,String color,int age){

        this(name,breed,color,age,null);

    }


    public Dog(String name,String breed,String color,int age,String greder){

        this.color=color;

        this.breed=breed;

        this.name=name;

        this.age=age;

        this.greder=greder;

    }

this()代表的是当前这个类的构造方法。

无参构造

public Dog(){}

全参构造

public Dog(String name,String breed,String color,int age,String greder){ this.color=color; this.breed=breed; this.name=name; this.age=age; this.greder=greder; }

全参构造就是将这个类中所有的属性都进行赋值操作,使用this()要保留这个全参构造.

最后留一句话: 方法重载发生在一个类中。

7.8 对象数组

代码语言:javascript复制
public class Student {

    String name;

    String phone;


    public String toString(){

        return this.name "t" this.phone;

    }

}
代码语言:javascript复制
Student[] stus=new Student[3];

注意: Student[] stus=new Student[3]; 只是在内存中分配了三个连续的Student类型的空间,并没有具体的内容,所以不能对元素直接进行操作

代码语言:javascript复制
错误案例:
public class Demo3 {

    public static void main(String[] args) {

        Student[] stus=new Student[3];

        stus[0].name="张三";

        stus[0].phone="13312345678";

        System.out.println(stus[0]);

    }

}

程序运行,会报空指针异常的错误,这就是因为stus[0]第一个元素并没有进行具体的赋值就开始使用,而造成的结果。

换种方式来讲:

代码语言:javascript复制
public class Demo3 {

    public static void main(String[] args) {

        Student[] stus=new Student[3];

        Student stu1;

        Student stu2;

        Student stu3;

    }

}

stu1,stu2,stu3和 Student[] stus=new Student[3];本质上并无太大的差异,大家都知道stu1,stu2,stu3在没有具体赋值的情况下是不能使用的。所以Student[] stus=new Student[3];与stu1,stu2,stu3情况是一样的,没有具体赋值

结论:对象数组在使用的时候里面的元素一定要先赋值再使用。

正确的案例:

代码语言:javascript复制
import java.util.Scanner;


public class Main2 {

    public static void main(String[] args) {

        //定义出一个三个长度的Student对象数组

        Student[] stus=new Student[3];

        Scanner input = new Scanner(System.in);

        for (int i = 0; i < stus.length; i  ) {

            //为每一个元素进行具体的赋值

            stus[i]=new Student();

            System.out.println("请输入第" (i 1) "名同学的姓名:");

            stus[i].name=input.next();//元素中的属性进行赋值

            System.out.println("请输入第" (i 1) "名同学的电话:");

            stus[i].phone=input.next();

        }


        System.out.println("姓名t电话");

        for (Student stu : stus){

            System.out.println(stu);

        }


    }

}

7.9 对象属性

就是在一个类中拥有另一个类的对象,例如

代码语言:javascript复制
public class Student {

    String name;

    String phone;

    Teacher teacher;  //对象属性


    public String toString(){

        return this.name "t" this.phone "t" this.teacher;

    }

}

对象属性可以在类中调用这个对象属性本身的属性和方法

在为对象属性赋值的时候,同样就先对对象属性进行new操作。

代码语言:javascript复制
public class Demo4 {

    public static void main(String[] args) {

        Student stu=new Student();

        stu.name="张三";

        stu.phone="1333333333";


        //单独创建老师对象

        Teacher tea=new Teacher();

        tea.name="李四";

        tea.age=28;

        tea.gender="男";

        tea.subject="数学";

  //将老师对象与学生对象中的teacher属性进行关联

        stu.teacher=tea;


        System.out.println(stu);

    }

}

对象属性的访问

当前对象.对象属性.属性

代码语言:javascript复制
public class Demo4 {

    public static void main(String[] args) {

        Student stu=new Student();

        stu.name="张三";

        stu.phone="1333333333";


        Teacher tea=new Teacher();

        tea.name="李四";

        tea.age=28;

        tea.gender="男";

        tea.subject="数学";



        stu.teacher=tea;

  //通过当前对象对对象属性进行属性访问

        System.out.println(stu.teacher.name);

        System.out.println(stu.teacher.subject);

    }

}

如果对象属性在定义的时候就已经new了,在使用的时候可以不再创建对象

代码语言:javascript复制
public class Student {

    String name;

    String phone;

    Teacher teacher=new Teacher();  //在定义的时候就已经new了


    public void study(){

        teacher.clazz();

        System.out.println(this.name "开始认真的学习");

    }


    public String toString(){

        return this.name "t" this.phone "t" this.teacher;

    }

}
代码语言:javascript复制
public class Demo4 {

    public static void main(String[] args) {

        Student stu=new Student();

        stu.name="张三";

        stu.phone="1333333333";


  //因为在定义的时候已经创建了,所以可以直接访问对象属性中的属性

        stu.teacher.name="李四";

        stu.teacher.age=28;

        stu.teacher.gender="男";

        stu.teacher.subject="数学";



        System.out.println(stu.teacher.name);

        System.out.println(stu.teacher.subject);

    }

}

谢谢大家,今天的知识总结就到这啦!希望大家多多支持,我在很多平台都有博客论文,也希望大家多多照顾,栓Q了!!!

0 人点赞