第四章_面向对象编程(上)

目录

前言

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

 对象的内存解析​编辑

对象数组的内存解析​编辑

 方法参数传递机制1

方法参数传递机制2

 方法参数传递机制练习​编辑

类的成员构成v1.0

 类的成员构成v2.0

1 面向过程与面向对象

例子:人把大象装进冰箱

 2 Java语言的基本元素: 类和对象

 3 对象的创建和使用

 内存解析​编辑​编辑

 对象的创建和使用:匿名对象

4 类的成员之一: 属性(field)​编辑

 成员变量vs局部变量的内存位置​编辑

 5 类的成员之二: 方法(method)

 6 再谈方法

6.1 方法的重载(overload)

6.2 可变形参的方法​编辑

 6.3 方法参数的值传递机制(重点) 

 方法的参数传递

 例题1:方法的参数传递​编辑

 例题2:方法的参数传递

 例题3:方法的参数传递​编辑

 练习5:貌似是考查方法的参数传递​编辑

 练习6:将对象作为参数传递给方法​编辑

6.4 递归方法

 7 面向对象特征之一: 封装与隐藏

 8 类的成员之三: 构造器(或构造方法)

 总结:属性赋值过程​编辑

 拓展知识:JavaBean​编辑

 拓展知识:UML类图​编辑

 9 关键字:this的使用​编辑

 10 关键字:package、 import的使用

  关键字-package​编辑

 关键字—import​编辑

章节练习题及面试题

类的实例化

代码实现

编程题1

编程题2

方法的使用

哪个选项和show()方法重载

方法的声明与调用

方法的重载

写出输出结果

写出输出结果

以下代码的运行结果是什么?

面向对象性

面向对象三大特征的说明

作用域public,private,protected,以及默认不写时的区别

找错

Java的内存管理之垃圾回收(了解)

构造器

构造器Constructor是否可被override

编程创建一个Box类,在其中定义三个变量表示一个立方体的长、宽和高,定义一个方法求立方体的体积。创建一个对象,求给定尺寸的立方体的体积。

定义一个圆类型

设计一个Dog类,有名字、颜色和年龄属性,定义构造器初始化这些属性,定义输出方法show()显示其信息。

定义一个类,用于描述坐标点

写一个人的类

写一个汽车类:

写一个课程类:

以下程序的运行结果是:

关于参数传递

练习一

练习二

练习三

练习四

练习五

练习六

以下代码的执行结果是什么

以下程序的运行结果:

以下代码的运行结果是?

简答

实验1:Account_Customer

实验2:Account_Customer_Bank


前言

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

 对象的内存解析

对象数组的内存解析

 方法参数传递机制1

方法参数传递机制2

 方法参数传递机制练习

类的成员构成v1.0

 

 类的成员构成v2.0

1 面向过程与面向对象

 

面向过程(POP) 与 面向对象(OOP)

 二者都是一种思想,面向对象是相对于面向过程而言的。面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。面向对象,将功能封装进对 象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。

 面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如 抽象、分类、继承、聚合、多态等。

 面向对象的三大特征

封装 (Encapsulation) 继承 (Inheritance) 多态 (Polymorphism)

面向对象:Object Oriented Programming 面向过程:Procedure Oriented Programming

例子:人把大象装进冰箱

 

 

 

 2 Java语言的基本元素: 类和对象

 

 

 

 

 

 

 3 对象的创建和使用

 

 

 

 

 

 

 

 

 

 内存解析

 

 

 

 

 

 对象的创建和使用:匿名对象

我们也可以不定义对象的句柄,而直接调用这个对象的方法。这 样的对象叫做匿名对象。

如:new Person().shout();

 使用情况

如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。

我们经常将匿名对象作为实参传递给一个方法调用。

4 类的成员之一: 属性(field)

 

 

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

 

 5 类的成员之二: 方法(method)

 

 

 

 

 

 

 

 

 6 再谈方法

6.1 方法的重载(overload)

 

 

 

 

6.2 可变形参的方法

 

 6.3 方法参数的值传递机制(重点) 

 方法的参数传递

 

 例题1:方法的参数传递

参数类型为:基本数据类型 

 例题2:方法的参数传递

 参数类型为:引用数据类型

 例题3:方法的参数传递

 

 练习5:貌似是考查方法的参数传递

 

 

 练习6:将对象作为参数传递给方法

6.4 递归方法

 

 

 7 面向对象特征之一: 封装与隐藏

为什么需要封装?封装的作用和含义?

 我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内 部的结构吗?有必要碰电动机吗?

 我要开车,…

 我们程序设计追求“高内聚,低耦合”。

 高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;

 低耦合 :仅对外暴露少量的方法用于使用。

 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提 高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露 的暴露出来。这就是封装性的设计思想。

 

 

 

 

 

 8 类的成员之三: 构造器(或构造方法)

 

 

 

 

 

 

 

 总结:属性赋值过程

 拓展知识:JavaBean

 

 拓展知识:UML类图

 9 关键字:this的使用

 

 

 

 

 

 

 10 关键字:package、 import的使用

  关键字-package

 

 

 

 

 

 关键字—import

 注意

1. 在源文件中使用import显式的导入指定包下的类或接口

2. 声明在包的声明和类的声明之间。

3. 如果需要导入多个类或接口,那么就并列显式多个import语句即可

4. 举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。

5. 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。

6. 如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的 是哪个类。

7. 如果已经导入java.a包下的类。那么如果需要使用a包的子包下的类的话,仍然需要导入。 8. import static组合的使用:调用指定类或接口下的静态的属性或方法

章节练习题及面试题

类的实例化

代码实现

编写一个Student类,包含name、gender、age、id、score属性,分别为String、String、int、int、double类型。

类中声明一个say方法,返回String类型,方法返回信息中包含所有属性值。

在另一个StudentTest类中的main方法中,创建Student对象,并访问say方法和所有属性,并将调用结果打印输出。

编程题1

定义一个丈夫Husband类,有姓名、年龄、妻子属性

定义一个妻子Wife类,有姓名、年龄、丈夫属性

丈夫类中有一个getInfo方法,其中,能显示自己的姓名,年龄,和他的妻子的姓名,年龄

妻子类中有一个getInfo方法,其中,能显示自己的姓名,年龄,和她的丈夫的姓名,年龄

定义一个测试类,创建妻子和丈夫对象,然后测试

编程题2

定义银行账户类Account,有属性:卡号cid,余额balance,所属用户Customer  

银行账户类Account有方法:

(1)getInfo(),返回String类型,返回卡的详细信息

(2)取钱方法withdraw(),参数自行设计,如果取钱成功返回true,失败返回false

(3)存钱方法save(),参数自行设计,如果存钱成功返回true,失败返回false

  

其中Customer类有姓名、身份证号、联系电话、家庭地址等属性

    Customer类有方法say(),返回String类型,返回他的个人信息。

在测试类Bank中创建银行账户类对象和用户类对象,并设置信息,与显示信息

方法的使用

哪个选项和show()方法重载

class Demo{

    void show(int a,int b,float c){}

}

A.void show(int a,float c,int b){}//yes

B,void show(int a,int b,float c){}//一模一样。不可以出现在同一个类中。

C.int show(int a,float c,int b){return a;}//yes。

D.int show(int a,float c){return a;}//yes

方法的声明与调用

(1)声明一个圆柱体类型,

(2)声明属性:底边的半径,和高

(3)声明方法:

A:方法的功能:在方法中打印圆柱体的详细信息

       圆柱体的底边的半径是xxx,高是xxx,底面积是xxx,体积是xxx。

B:方法的功能:返回底面积

C:方法的功能:返回体积

D:方法的功能:为圆柱体的底边的半径,和高赋值

E:方法的功能:为圆柱体的底边的半径,和高赋值,并返回赋值的结果

       如果底边的半径或高为<=0,赋值失败,返回false,否则返回true

(4)并测试     

/*

(1)声明一个圆柱体类型,

(2)声明属性:底边的半径,和高

(3)声明方法:

A:方法的功能:在方法中打印圆柱体的详细信息

         圆柱体的底边的半径是xxx,高是xxx,底面积是xxx,体积是xxx。

B:方法的功能:返回底面积

C:方法的功能:返回体积

D:方法的功能:为圆柱体的底边的半径,和高赋值

E:方法的功能:为圆柱体的底边的半径,和高赋值,并返回赋值的结果

         如果底边的半径或高为<=0,赋值失败,返回false,否则返回true

(4)并测试 

*/

//声明圆柱体

class Cylinder{

         double radius;//底边半径

         double height;//高

        

         /*

         A:方法的功能:在方法中打印圆柱体的详细信息

         圆柱体的底边的半径是xxx,高是xxx,底面积是xxx,体积是xxx。

         */

         void printDetails(){

                   //double area = Math.PI * radius * radius;//底面积

                   //double volume = area * height;//体积

                  

                   //System.out.println("圆柱体的底边的半径是" + radius +" ,高是" + height + ",底面积是"+ area +",体积是"+volume +"。");

        

                   //调用本类的方法

                   System.out.println("圆柱体的底边的半径是" + radius +" ,高是" + height + ",底面积是"+ getArea() +",体积是"+getVolume() +"。")

         }

        

         //B:方法的功能:返回底面积

         double getArea(){

                   double area = Math.PI * radius * radius;//底面积

                   return area;

         }

        

         //C:方法的功能:返回体积

         double getVolume(){

                  

                  //double area = Math.PI * radius * radius;//底面积

                   //double volume = area * height;//体积

                   //return volume;

                  

                   double volume = getArea() * height;//体积

                   return volume;

         }

        

         //D:方法的功能:为圆柱体的底边的半径,和高赋值

         void setValue(double r, double h){

                   radius = r;

                   height = h;

         }

        

         /*

         E:方法的功能:为圆柱体的底边的半径,和高赋值,并返回赋值的结果

         如果底边的半径或高为<=0,赋值失败,返回false,否则返回true

         */

         boolean setRadiusAndHeight(double r, double h){

                   if(r<=0 || h<=0){

                            return false;

                   }

                   //radius = r;

                   //height = h;

                   setValue(r,h);

                   return true;

         }

        

}

class TestMethodExer{

         public static void main(String[] args){

                   //1、创建对象

                   Cylinder c = new Cylinder();

                   //c.radius = 2.0;

                   //c.height = 2;

                   c.setValue(2.0,2);

                  

                   c.printDetails();

                  

                   System.out.println("底面积: " + c.getArea());

                   System.out.println("体积: " + c.getVolume());

                  

                   boolean flag = c.setRadiusAndHeight(3.0, 5);

                   if(!flag){// 如果flag = false, !flag结果就是true,条件成立

                            System.out.println("赋值失败");

                   }else{

                            c.printDetails();

                   }

         }

}

方法的重载

方法重载(overload)必须满足________

A. 在不同class中定义的方法     B.在同一类型中定义的方法

C. 方法名必须相同              D.返回类型必须相同

E. 参数一定不同                F.参数可以相同

答案:BCE

写出输出结果

class Demo{

public static void main(String[] args){

show(0);

show(1);

}

public static void show(int i){

switch(i){

default:

i+=2;

case 1:

i+=1;

case 4:

i+=8;

case 2:

i+=4;

}

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

}

}

写出输出结果

class Demo{

public static void main(String[] args){

int x = 1;

for(show('a'); show('b') && x<3; show('c')){

show('d');

x++;

}

}

public static boolean show(char ch){

System.out.print(ch);

return true;

}

}

//答案:abdcbdcb

以下代码的运行结果是什么?

public classTest1 {

    public static booleanfoo(char c) {

        System.out.print(c);

        return true;

    }

    public static voidmain(String[]args) {

        int i= 0;

        for(foo('A'); foo('B') && (i< 2); foo('C')) {

            i++;// 1 2

            foo('D');

        }

    }

}

答案:ABDCBDCB

面向对象性

面向对象三大特征的说明

答:面向对象有三大特点:封装、继承、多态。(如果要回答四个,可加上 抽象性 这一特点)

1.继承性:

继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。

2.封装性:

封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。

3. 多态性:

多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

4.抽象性:

抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

作用域public,private,protected,以及默认不写时的区别

找错

public class Something {

   void doSomething () {

       private String s = "";

       int l = s.length();

   }

}

有错吗?

答案: 错。局部变量前不能放置任何访问修饰符 (private,public,和protected)。

Java的内存管理之垃圾回收(了解)

分配:由JVM自动为其分配相应的内存空间

释放:由JVM提供垃圾回收机制自动的释放内存空间

垃圾回收机制(GC:Garbage Collection):将垃圾对象所占用的堆内存进行回收。Java的垃圾回收机制是JVM提供的能力,由单独的系统级垃圾回收线程在空闲时间以不定时的方式动态回收。

垃圾对象:不再被任何引用指向的对象。

面试题:

问:在程序中是否可以通知垃圾回收机制过来回收垃圾?

能,通过调用System.gc();或Runtime.getRuntime().gc();

再问:调用了System.gc();或Runtime.getRuntime().gc();后是立刻执行垃圾回收吗?

不是,该调用并不会立刻启动垃圾回收机制开始回收,但会加快垃圾回收机制的运行。

public class TestGC{

         public static void main(String[] args)throws Exception{

                   for(int i=0; i<10; i++){

                            MyClass m = new MyClass();//这里本次循环完,本次创建的对象就成为垃圾了

                            System.out.println("创建第" + (i+1) + "的对象:" + m);

                   }

                  

                   //通知垃圾回收机制来收集垃圾

                   System.gc();

                  

                   //为了延缓程序结束

                   for(int i=0; i<10; i++){

                            Thread.sleep(1);

                            System.out.println("程序在继续....");

                   }

         }

}

class MyClass{

         //这个方法是垃圾回收机制在回收它的对象时,自动调用,理解成对象留临终遗言的方法

         public void finalize(){

                   System.out.println("轻轻的我走了.....");

         }

}

构造器

构造器Constructor是否可被override

答:构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload

编程创建一个Box类,在其中定义三个变量表示一个立方体的长、宽和高,定义一个方法求立方体的体积。创建一个对象,求给定尺寸的立方体的体积。

(提供无参的构造器和一个有参的构造器)

定义一个圆类型

提供显示圆周长功能的方法

提供显示圆面积的方法

提供无参的构造器和一个有参的构造器

设计一个Dog类,有名字、颜色和年龄属性,定义构造器初始化这些属性,定义输出方法show()显示其信息。

提供无参的构造器和一个有参的构造器

定义一个类,用于描述坐标点

0——————>X

          |

          |

          |          P(X,Y)

          |

          |

          Y 

(1)具有计算当前点到原点距离的功能

(2)求到任意一点(m,n)的距离

(3)求到任意一点(Point p)的距离

(4)具有坐标点显示功能,显示格式(x,y)

(5)提供无参的构造器和一个有参的构造器

写一个人的类

属性:名字,性别,年龄;提供无参的构造器和一个有参的构造器

方法:(1)自我介绍的方法(2)吃饭的方法

创建一个对象“张三”

写一个汽车类:

属性:品牌;车长;颜色;价格;

创建五个对象:“捷达”,“宝马”,“劳斯莱斯”,“科鲁兹”,“迈锐宝”

提供无参的构造器和一个有参的构造器

写一个课程类:

属性:课程名;学时;任课老师;

创建五个对象:“c语言”,“java编程”,“php网络编程”,“c++”,“数据结构”

提供无参的构造器和一个有参的构造器

以下程序的运行结果是:

public classTest1 {

    public static voidmain(String[]args) {

        newA(newB());

    }

}

classA{

    publicA(){

        System.out.println("A");

    }

    publicA(Bb){

        this();

        System.out.println("AB");

    }

}

classB{

    publicB(){

        System.out.println("B");

    }

}

答案:

B

A

AB

关于参数传递

练习一

写出结果。

public class Test{

public static void leftshift(int i, int j){

        i+=j;

}

public static void main(String args[]){

int i = 4, j = 2;

leftshift(i, j);

System.out.println(i);

}

}

答案:

4.  和leftShift函数没关系。

练习二

写出结果。

public class Demo{

public static void main(String[] args){

int[] a=new int[1];

modify(a);

System.out.println(a[0]); //

}

public static void modify(int[] a){

a[0]++;

}

}

答案: 1

练习三

public class TestA {

int i ;

void change(int i){

i++;

System.out.println(i);

}

void change1(TestA t){

t.i++;

System.out.println(t.i);

}

public static void main(String[] args) {

TestA ta = new TestA();

System.out.println(ta.i); //

ta.change(ta.i);//

System.out.println(ta.i); //

ta.change1(ta);  //

System.out.println(ta.i);//

}

}

练习四

写出结果

class Value{

    int i = 15;

}

class Test{

public static void main(String argv[]) {

Test t = new Test();

t.first();

}

public void first() {

int i = 5;

Value v = new Value();

v.i = 25;

second(v, i);

System.out.println(v.i);

}

public void second(Value v, int i) {

i = 0;

v.i = 20;

Value val = new Value();

v = val;

System.out.print(v.i + " " + i);

}

}

A.15 0 20

B.15 0 15

C.20 0 20

D.0 15 20

A is correct.

练习五

1. public class Test {

2. int x= 12;

3. public void method(int x) {

4. x+=x;

5. System.out.println(x);

6. }

7. }

Given:

34. Test t = new Test();

35. t.method(5);

What is the output from line 5 of the Test class?

A. 5

B. 10

C. 12

D. 17

E. 24

练习六

import java.util.Arrays;

public class PassValueExer2{

         public static void main(String[] args){

                   int[] array = {3,2,5,1,7};

                  

                   //调用sort方法,实现从大到小排序

                   //在此处补充代码

                   ....

                  

                   //显示结果

                   System.out.println("排序后的结果是:" + Arrays.toString(array));

         }

        

         //要求使用冒泡排序完成

         public void sort(//形参?){

                  

         }

}

答案:

/*

考点:

1、方法的参数传递机制

2、冒泡排序

*/

import java.util.Arrays;

public class PassValueExer2{

         public static void main(String[] args){

                   int[] array = {3,2,5,1,7};

                   PassValueExer2 exer = new PassValueExer2();

                   //调用sort方法,实现排序

                   exer.sort(array);//实参给形参的是地址,数组的首地址

                  

                   //遍历结果

                   System.out.println("排序后的结果是:" + Arrays.toString(array));

         }

        

         //功能:用冒泡排序,实现为数组排序,而且从大到小

         //形参的类型?我要把什么传过来

         //传递数组

         //接收的类型也肯定是数组,即形参接收实参,即形参的类型是int[]

         public void sort(int[] arr){

                   //冒泡排序

                   //在这里对谁排,对arr进行排序

                   for(int i=1; i<arr.length; i++){//多少轮

                            //每一轮,从左往后--》for(int j=0;...)

                            //要实现从大到小-->前面的元素比后面的元素小,就交换

                            //每一轮几次,

                            //假设,数组的长度为5

                            //第一轮:4次,i=1, j=0,1,2,3  j<4  j< arr.length-i

                            //第二轮:3次,i=2, j=0,1,2

                            for(int j=0; j<arr.length-i; j++){

                                     if(arr[j] < arr[j+1]){

                                               int temp = arr[j];

                                               arr[j] = arr[j+1];

                                               arr[j+1] = temp;

                                     }

                            }

                   }

         }

}

以下代码的执行结果是什么

    public static voidmain(String[]args) {

        int i= 0;

        change(i);

        i=i++;

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

    }

    public static voidchange(int i){

        i++;

    }

答案:i = 0

以下程序的运行结果:

    public static voidmain(String[]args) {

        Stringstr=newString("world");

        char[]ch=new char[]{'h','e','l','l','o'};

        change(str,ch);

        System.out.println(str);

        System.out.println(String.valueOf(ch));

    }

    public static voidchange(Stringstr,char[]arr){

        str="change";

        arr[0] ='a';

        arr[1] ='b';

        arr[2] ='c';

        arr[3] ='d';

        arr[4] ='e';

    }

答案:

world

abcde

以下代码的运行结果是?

public classTest {

    int a;

    int b;

    public voidf(){

        a= 0;

        b= 0;

        int[]c= {0};

        g(b,c);

        System.out.println(a+" "+b+" "+c[0]);

    }

    public voidg(int b,int[]c){

        a= 1;

        b= 1;

        c[0] = 1;

    }

    public static voidmain(String[]args) {

        Testt=newTest();

        t.f();

    }

}

答案:1 0 1

简答

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的

补足compare函数内的代码,不许添加其他函数。

classCircle {

    private double radius;

    publicCircle(double r) {

       radius=r;

    }

    publicCircle compare(Circlecir){

       //程序代码

       /*

        * if(this.radius>cir.radius) return this; return cir;

        */

       // return (this.radius>cir.radius)?this: cir;

    }

}

classTC {

    public static voidmain(String[]args) {

       Circlecir1=newCircle(1.0);

       Circlecir2=newCircle(2.0);

       Circlecir;

       cir=cir1.compare(cir2);

       if(cir1==cir)

           System.out.println("1的半径比较大");

       else

           System.out.println("2的半径比较大");

    }

}

实验1:Account_Customer

 3.写一个测试程序。

(1) 创建一个 Customer ,名字叫 Jane Smith, 他有一个账号为 1000,余额为 2000 元, 年利率为 1.23% 的账户。

(2) 对 Jane Smith 操作。 存入 100 元,再取出 960 元。再取出 2000 元。 打印出 Jane Smith 的基本信息

成功存入 :100.0

成功取出:960.0

余额不足,取款失败

Customer [Smith, Jane] has a account: id is 1000, annualInterestRate is 1.23%, balance is 1140.

实验2:Account_Customer_Bank

 

 

 


版权声明:本文为qq_35426036原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。