java面向对象初始与值传递

java的面相对象感觉很有活力比python那种简便化的面相对象有趣多了,何谓面相对象什么是面向对象,这个话题一直是很多人和面试官会去深究的问题,,

面向对象思想是将人们在现实生活中的事物应用到程序设计中。对象就是现实生活中真实存在的,比如某个人某个事物这都是可以叫做一个对象

 

 

类:

  将具有相同属性及相同行为的一组对象称为类。广义地讲,具有共同性质的事物
的集合就称为类。
eg:一匹马是一个类。而马就是对象。类可以理解为这个对象中的一个实例而对象是一个大的泛指


面向对象的程序设计有三个主要特征,如下:

封装性 继承性 多态性

 

 

首先先创建一个简单的类和对象

 

public class clas {

    public static void main(String[] args) {
        // 首先想要调用类中的信息要先是实例化一个对象类操作

        Person p1 = new Person();
        //然后通过对象给类中的信息赋值
        p1.name = "隔壁老王";
        p1.age = 17;
        p1.talk();   // 我是隔壁老王今年:17
    }
}

class Person{ //类
    String name;  //属性
    int age;
    boolean isMarried;
    public void walk(){ // 方法
        System.out.println("人走路");
    }
    public void eat(){
        System.out.println("人能吃");
    }
    void talk(){
        System.out.println("我是"+name+"今年:"+age);
    }
}

 

类中的方法是通过void来进行实现的。和python的def差不多

 

 

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

创建类中的方法一般需要加上void : void 方法名(){方法体}

注意:在整个java项目(java文件)中不可以出现相同的类,因为java在编译的时候上面的类编译之后 再识别出相同的就会报错,或者在倒入的时候也会导致识别出错

 

 

一个类可以有多个对象,实例化的对象的空间每一个都在内存中单独开辟一块空间互不干扰

 

如果类中有私有属性 private装饰的就不能直接调用或者赋值了不然就会报错

 

成员变量存储在堆中 是需要垃圾回收机制来处理,局部变量存储在栈中随着方法的结束而释放

 

 

 

 

 

 

 

练习:

编写教师类和学生类,并通过测试类创建对象进行测试
Student类
属性:
name:String age:int major:String interests:String
方法:say() 返回学生的个人信息
Teacher类
属性:
name:String age:int teachAge:int course:String
方法:say() 输出教师的个人信息

eg:

public class cls {
    public static void main(String[] args) {
        teacher te = new teacher();
        te.name = "王老师";
        te.age = 17;

        stu st = new stu();
        st.name = "小明";
        st.age = 16;
        te.say(st.name,st.age);
        st.say(te.name, te.age);
    }
}

class teacher{  //  老师类
    String name;
    int age;
    String major;
    String interests;
    void say(String name, int age){
        System.out.println("这个学生是:"+name+"年龄是:"+age);
    }

}

class stu{ // 学生类
    String name;
    int age;
    int teacherAge;
    String course;
    void say(String name, int age){
        System.out.println("这个老师是:"+name+"年龄是:"+age);
    }
}
View Code

 

 

方法的声明:

权限修饰符  返回值类型  方法名(形参列表){
                 方法体
          }

方法名:属于标识符,遵循标识符的规则和规范,“见名知意”

注意:我们再传递参数的时候也一定要把参数的类型传递进去不然会报错
public void addAge(int age){ // 传递参数把参数age的类型int也传递进去 age +=2; }

 

return :java中的return和python的return是一样的。都是返回结果 然后终止方法

 

方法可以分为void不带返回值的方法 和携带返回值的方法

class  te{
    String name;  // 成员变量
    int age;
    String major;

    void sys(){  // void不需要返回值
        int age;
    }

    public String getName(){
        return name;  // 因为方法体是没有void的就需要return来进行返回了
    }
}

 

注意:

在方法中可以调用方法:递归调用
但是不可以在方法中定义方法

 

 

 练习:

1、

编写程序,声明一个method方法,在方法中打印一个10*8 的*型矩形,在main方法中调用该方法
public class Usertest {
    public static void main(String[] args) {
        Usertest user = new Usertest();
        user.method();

    }


    public void method(){
        for(int i = 0; i < 10; i++ ){
            for(int j = 0; j < 8; j++){
                System.out.print("*");

            }
            System.out.println();
        }

    }
}
View Code

 

2、

修改上一个程序,在method方法中,除打印一个10*8的*型矩形外,再计算该矩形的面积,
 * 并将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。
public class Usertest {
    public static void main(String[] args) {
        Usertest user = new Usertest();

        int aray = user.method();
        System.out.println("矩形的面积是:"+aray);

    }

    public int  method(){
        for(int i = 0; i < 10; i++ ){
            for(int j = 0; j < 8; j++){
                System.out.print("*");

            }
            System.out.println();
        }
        return 10*8;  // 想要返回值就要把上面的方法定义为要放回值的类型
    }
}
View Code

 

 

3、

修改上一个程序,在method方法提供m和n两个参数,方法中打印一个m*n的*型矩形,
 * 并计算该矩形的面积, 将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。

 

public class Usertest {
    public static void main(String[] args) {
        Usertest user = new Usertest();

        int aray = user.method(10,5);   // 给参数
        System.out.println("矩形的面积是:"+aray);

    }

    public int  method(int m, int n){  // 传递参数
        for(int i = 0; i < m; i++ ){
            for(int j = 0; j < n; j++){
                System.out.print("*");

            }
            System.out.println();
        }
        return 10*8;  // 想要返回值就要把上面的方法定义为要放回值的类型
    }
}
View Code

 

对象数组题目

对象数组题目: 定义类Student,包含三个属性:学号number(int),年级state(int),成绩 score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。 
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息 提示:
1) 生成随机数:Math.random(),返回值类型double; 2) 四舍五入取整:Math.round(double d),返回值类型long。 5.声明一个日期类型MyDate:有属性:年year,月month,日day。创建2个日期 对象,分别赋值为:你的出生日期,你对象的出生日期,并显示信息。

第一种:

public class Usertest{
    public static void main(String[] args) {
        Stude [] stu = new Stude [20]; // 生成一个对象数组规定长度为20 因为要生成20个不能一个一个生成吧
        for(int i = 0; i < stu.length; i++){
            stu[i] = new Stude (); // 生成每一个对象的数组

            // 给每一个对象属性赋值
            stu[i].number = (i+1);

            //年纪[1, 6]
            stu[i].state = (int)(Math.random()*(6-1+1)+1);
            stu[i].score = (int)(Math.random()*(100-0-1)+1);
        }

        // 遍历学生数组
        for(int i = 0; i < stu.length; i++){
//            System.out.println(stu[i].number+","+stu[i].state+","+stu[i].score);
            System.out.println(stu[i].info());
        }

        System.out.println();

        // 求出三年级学生的的学生信息
        System.out.println("这是三年级学生的信息");
        for(int i = 0; i < stu.length; i++){
            if(stu[i].state == 3){

                System.out.println(stu[i].info());
            }

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

        // 使用冒泡排序对学生的成绩排序

        for(int i = 0; i < stu.length;i++){
            for(int j = 0; j < stu.length -i -1; j++){
                if(stu[j].score > stu[j+1].score){  // 两个值的转换必须要定义一个第三方数字不能像python一直直接交换
                    Stude tmp = stu[j];  // 参数的定义也要是对象数组的元素
                    stu[j] = stu[j+1];
                    stu[j+1] = stu[j];
                }
            }
        }
        for(int i = 0; i < stu.length; i++){
//            System.out.println(stu[i].number+","+stu[i].state+","+stu[i].score);
            System.out.println(stu[i].info());
        }

    }
    static class  Stude{   // 因为主类是static的  如果写在了公类里面 也要是static,除非是放在公类外部
        int number = 0; // 学号
        int state = 0; // 年纪
        int score = 0; //  成绩

        String info(){
            return "学号:"+number+" 年纪: "+state+" 成绩: "+score;
        }
    }
}
View Code

 

 第二种面向对象的额封装:

public class Usertestplus {
    public static void main(String[] args) {
        Student [] stu = new Student[20];
        for(int i = 0; i < stu.length; i++){
            stu[i] = new Student();  // 实例化每一个对象

            //为每一个对象的信息进行赋值
            stu[i].number = i+1;
            stu[i].state = (int)(Math.random()*(6-1+1)+1);
            stu[i].score = (int)(Math.random()*(100 -0 +1)+1);
        }


        // 因为方法是在公共类中的  需要公共类的对象来调用
        Usertestplus user = new Usertestplus();
        user.print(stu);


        //打印3年纪的学生的信息
        System.out.println("打印3年纪学生的信息");
        user.searchState(stu,3);


        //使用冒泡排序来进行信息排序
        System.out.println("使用冒泡进行排序");
        user.sort(stu);

        // 对排序后的 信息进行遍历

        user.print(stu);

    }


    // 遍历信息

    static void print(Student[] stu){  // 把定义的类数组给传递进来
        for(int i = 0; i < stu.length; i++){
            System.out.println(stu[i].info());

        }
    }

    //查找 3年纪的学生的信息
    static void searchState(Student [] stu, int state){
        for(int i = 0 ;i < stu.length; i++){
            if(stu[i].state == state){
                System.out.println(stu[i].info());
            }
        }
    }

    //排序
    static void sort(Student [] stu){
        for(int i = 0; i<stu.length; i++){
            for(int j = 0; j < stu.length-i-1; j++){
                if(stu[j].score > stu[j+1].score){
                    Student tmp = stu[j];
                    stu[j]= stu[j+1];
                    stu[j+1] = tmp;
                }

            }

        }


    }

}




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

    public String info(){
        return "学号:"+number+" 年纪:"+state+" 成绩:"+score;
    }
}
View Code

 

 

对象的内存解析:

 

 

 

 匿名对象:

即没有对这个对象赋名。每一次使用都要new一个

        Person p1 = new Person();
        //然后通过对象给类中的信息赋值
        p1.name = "隔壁老王";
        p1.age = 17;
        p1.talk();   // 我是隔壁老王今年:17
        
        //上面是创建了有名对象每次使用都通过这个对象名去调用
        // 匿名对象:
        new Person().age=16; // 通过匿名对象去调用
        new Person().name = "老李";// 这两个匿名对象是不同的 

 

 

每一次创建的匿名对象是不同的:

public class clas {

    public static void main(String[] args) {
        // 首先想要调用类中的信息要先是实例化一个对象类操作

        Person p1 = new Person();
        //然后通过对象给类中的信息赋值
        p1.name = "隔壁老王";
        p1.age = 17;
        p1.talk();   // 我是隔壁老王今年:17

        //上面是创建了有名对象每次使用都通过这个对象名去调用
        // 匿名对象:
        new Person().age=16; // 通过匿名对象去调用
        new Person().name = "老李";// 这两个匿名对象是不同的
        new Person().talk(); //   我是null今年:0  这里的值是都不同的  所以对象都是不同的


    }
}

class Person{
    String name;
    int age;
    boolean isMarried;
    public void walk(){
        System.out.println("人走路");
    }
    public void eat(){
        System.out.println("人能吃");
    }
    void talk(){
        System.out.println("我是"+name+"今年:"+age);

    }
}

 

 方法的重载:即一个类中可以出现多个名字相同的方法 只要参数的个数或者类型不同即可,甚至两个参数的位置不同的 时候也会认为是两个不同的方法

 

    String name;
    int age;
    boolean isMarried;
    public void walk(){
        System.out.println("人走路");
    }
    public void eat(){
        System.out.println("人能吃");
    }
    
    //如下的两个方法构成了方法的重载
    void talk(){
        System.out.println("我是"+name+"今年:"+age);

    }

    void talk(int age){
        System.out.println(age);
    }
}

判断是否是重载:

跟方法的权限修饰符、返回值类型、行参变量名、方法体都没有关系

 

习题:判断是否是重载

与void show(int a,char b,double c){}构成重载的有: 
a) void show(int x,char y,double z){} // no b) int show(int a,double c,char b){} // yes c) void show(int a,double c,char b){} // yes d) boolean show(int c,char b){} // yes e) void show(double c){} // yes f) double show(int x,char y,double z){} // no
g) void shows(){double c}
// no

练习:

编写程序,定义三个重载方法并调用。方法名为mOL。 三个方法分别接收一个int参数、两个int参数、一个字符串参数。分别
执行平方运算并输出结果,相乘并输出结果,输出字符串信息。 在主类的main ()方法中分别用参数区别调用三个方法。
3.定义三个重载方法max(),第一个方法求两个int值中的最大值,第二个方 法求两个double值中的最大值,第三个方法求三个double值中的最大值, 并分别调用三个方法
public class clas {

    public static void main(String[] args) {
        // 首先想要调用类中的信息要先是实例化一个对象类操作

        Person p1 = new Person();
        //然后通过对象给类中的信息赋值
        p1.name = "隔壁老王";
        p1.age = 17;
        p1.talk();   // 我是隔壁老王今年:17

        //上面是创建了有名对象每次使用都通过这个对象名去调用
        // 匿名对象:
        new Person().age=16; // 通过匿名对象去调用
        new Person().name = "老李";// 这两个匿名对象是不同的
        new Person().talk(); //   我是null今年:0  这里的值是都不同的  所以对象都是不同的


        // 
        System.out.println(p1.mOl(3));  // 9
        System.out.println(p1.mOl(3,6));  // 18
        System.out.println(p1.mOl("lao"));  // 这个是:lao

        System.out.println(p1.max(3,7));  //7
        System.out.println(p1.max(3.2,5.64));  //5。64


    }
}

class Person{
    String name;
    int age;
    boolean isMarried;
    public void walk(){
        System.out.println("人走路");
    }
    public void eat(){
        System.out.println("人能吃");
    }

    //如下的两个方法构成了方法的重载
    void talk(){
        System.out.println("我是"+name+"今年:"+age);

    }

    void talk(int age){
        System.out.println(age);
    }


    int mOl(int num){
        return num*num;
    }

    int mOl(int num, int number){
        return num*number;
    }
    String mOl(String str){
        return "这个是:"+str;
    }

    int max(int num, int number){
        int max = (num > number)? num :number;
        return max;

    }

    double max(double num, double number){
        double max =(num > number)? num :number;
        return max;

    }
}
View Code

 

 可变形参:

可变行参的格式:  数据类型....变量名

oublic vold nick(String .... name){  // 可以给nick这个方法传递无限多个的字符串类型的参数


}

当调用可变个数行参的方法时,传入的参数可以是0个1个或者多个

 

 变量的赋值:

如果变量是基本数据类型,此时赋值的变量是变量所保存的数据值

如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值

如果参数是基本数据类型,此时实参赋值给形参的是实参的真实的数据值
  

 

参数的赋予的时候地址的转换:

两个参数的值的赋予:普通数据类型在赋值的时候是只有一个栈空间的。把值在copy一份给另一个参数的。引用数据类型的值的赋予时候是堆空间都指向同一个 只有栈空间的名字不同,所以当一个改变的时候会带动堆空间的值的改变那就是都改变了

 

 

 

 

 

引用数据类型赋值

 

 

 

 

基础数据和引用数据在值的交换的注意

public class swap {
    public static void main(String[] args) {
        swap sw = new swap();  // 创造公共类对象
        swp s = new swp();
        s.m =19;
        s.n=6;
        s.swap(s.m,s.n);
        System.out.println("m: "+s.m+"n:"+s.n);  // m :19 , n:6   大家思考下为什么没有换成呢? 因为 你这个m的值和下面的方法中的值是两个了   因为此时的m和n是基础数据类型在栈中有不同的位置 方法中换了
                                        但是最初定义的没有换
sw.swap(s); // 因为方法定义在公共类中只能通过公共类来调用 System.out.println("m: "+s.m+"n:"+s.n); //m: 6n:19 因为引用数据类型的值指向的都是一样的所以可以交换成功 } public void swap(swp s){ //使用引用数据类型来当行参 int tmp = s.m; s.m = s.n; s.n = tmp; } } class swp{ int m; int n; public void swap(int m, int n){ int tmp = m; m = n; n = tmp; } }

 

 

行参是方法定义时,声明在小括号内的参数

实参:方法调用时,实际传递给行参的数据

 

例题

public class AprilThreeAfternoonTestOne {
    public static void main(String[] args) {
        AprilThreeAfternoonTestOne aprilThreeAfternoonTestOne = new AprilThreeAfternoonTestOne();
        aprilThreeAfternoonTestOne.first();
    }
    
    public void first(){
        int i = 5;
        AprilThreeAfternoon aprilThreeAfternoon = new AprilThreeAfternoon();
        aprilThreeAfternoon.i = 25;
        second(aprilThreeAfternoon,i);
        System.out.println(aprilThreeAfternoon.i);

    }
    
    public void second(AprilThreeAfternoon aprilThreeAfternoon, int i){
        i = 0;
        aprilThreeAfternoon.i = 20;
        AprilThreeAfternoon af = new AprilThreeAfternoon();
        aprilThreeAfternoon = af;
        System.out.println(aprilThreeAfternoon.i +" "+ i );
    }
}


class AprilThreeAfternoon{
    int i = 15;
}
求出结果

 

15 0
20

20 是因为在second结束之后就释放了所覆盖的所以又回到了以前所赋值的
结果

 

 

 

 

面试题:

定义一个int型的数组:int[] arr = new int[]{12,3,3,34,56,77,432}; 让数组的每个位置上的值去除以首位置的元素,得到的结果,作为该位置上的 新值。遍历新的数组

答案:

//错误写法   
for(int i= 0;i < arr.length;i++){  因为这样就会把除去的数字当作第一位数字了
arr[i] = arr[i] / arr[0]; }


//正确写法1
for(int i = arr.length – 1;i >= 0;i--){
arr[i] = arr[i] / arr[0]; }
//正确写法2
int temp = arr[0];
for(int i= 0;i < arr.length;i++){
arr[i] = arr[i] / temp; }

 

 计算1-100直接所有自然数的和:

    public static void main(String[] args) {
        jia ji = new jia();
        System.out.println(ji.sum(100));

    }
    public int sum(int num){
        if(num == 1){
            return 1;
        }else {
            return num+sum(num-1);
        }

    }
}
View Code

 

 

 

 

posted @ 2019-04-15 14:59  可爱的红领巾  阅读(1059)  评论(0编辑  收藏  举报