一、面向对象思想编程内容的三条主线分别是什么:

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

问:面向对象的编程思想?

答(大概描述):类、对象;面向对象的三大特征;等等。

二、谈谈你对面向对象中类和对象的理解,并指出二者的关系。

面试:举例在开发当中的某个类,某个使用场景、常见的开发问题,举例开发中的例子。(写了某个类,调用什么实例化实现了什么功能)

类和对象的理解:

  1. 类:抽象的、概念上的内容。<br /> 对象:实实在在存在的一个个体。

二者关系:

  1. 对象是由类派生出来的(new出来的)。对象是我们类的实例

三、面向对象思想的体现一:

类和对象的创建和执行操作有拿三步:

  1. 1.创建类,设计类的成员。<br /> 2.创建类的对象(类的实例化)。<br /> 3.通过调用对象的结构,来完成功能的设计:“对象.属性”,“对象.方法”。<br />补充:几个概念的使用说明:<br /> 属性=成员变量=filed=域、字段<br /> 方法=成员方法=函数=method<br /> 创建类的对象=类的实例化=实例化类

四、画出如下代码在执行时的内存分配情况。

  1. class Car{
  2. String color="red";
  3. int num=4;
  4. void show(){
  5. int a=10;
  6. System.out.println("color="+color+",num="+num);
  7. }
  8. }
  9. class CarTest{
  10. public static void main(String[] args){
  11. Car c1=new Car();
  12. Car c2=new Car();
  13. c1.color="blue";
  14. c1.show();
  15. c2.show();
  16. }
  17. }

1.先看执行代码创建的实例化对象,放入栈空间。
image.png
2.再看对象中传入的值,初始为空,把传入的是写上:
image.png
3.修改c1改变的值:
image.png
4.然后从c1、c2分别调用了show方法,把a传入,输出结果:
image.png
如图:按照上面的步骤画出流程图(static放栈空间,局部变量放在栈空间。非static放堆空间):
image.png

五、类的方法是否可以定义变量?是否可以调用属性?是否可以定义方法?是否可以调用方法?

类的方法可以定义变量可以调用属性不可以在内部再定义方法可以调用其他的方法

六、JVM的内存结构

编译完源程序以后,生成一个或多个字节码文件。
我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。

虚拟机栈,即为平时提到的栈结构,我们将局部变量存储再栈结构中。

堆,我们将new出来的结构(比如:数组、对象)加载在堆空间中。

补充:对象的属性(非static的)加载在堆空间中。

** 方法区:类的加载信息、常量池、静态域。**

七、类的结构之一:属性

1.变量的分类

(1)按照数据类型:image.png

(2)按照在类中声明的位置:

image.png

八、类的结构之二:方法

1.方法的结构:
  1. 方法的声明:权限修饰符 返回值类型 方法名(形参列表){ 方法体 }

注:static、final、abstract来修饰的方法,后面再详细描述。

2.return关键字的使用:
  1. 1)使用范围:使用在方法体中<br /> 2)作用:①结束方法<br /> ②针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。

注:return关键字后面不可以声明执行语句

注:方法A中又调用了方法A,该方法称为递归方法。

九、理解“万事万物皆对象”

1.在java语言范畴中,我们都将功能、结构等都封装到类当中,通过类的实例化,来调用具体的功能结构
>Scanner,String等
>文件:File
>网络资源:URL
2.涉及到java语言与前端的Html、后端的数据交互时,前后端的结构在Java层面交互时,都体现为类、对象。

十、匿名对象的使用(开发中的使用:一般使用形参定义它的名,然后直接传入new的对象,就叫做匿名对象)

  1. public class InstanceTest{
  2. public static void main(String[] args){
  3. PhoneMall mall=new PhoneMall();
  4. mall.show(new Phone());
  5. }
  6. }
  7. class PhoneMall{
  8. public void show(Phone phone){
  9. phone.sendEmail();
  10. phone.playGame();
  11. }
  12. }
  13. class Phone{
  14. public void sendMail(){
  15. System.out.println("发送邮件");
  16. }
  17. public void playGame(){
  18. System.out.println("玩游戏");
  19. }
  20. }

十一、自定义数组的工具类

1.ArrayUtil工具类:

  1. /*
  2. * 自定义数组的工具类
  3. */
  4. public class ArrayUtil {
  5. //冒泡排序
  6. public void sort(int[] arr){
  7. for (int i=0;i<arr.length;i++){
  8. for (int j=0;j<arr.length-1-i;j++){
  9. if (arr[j]>arr[j+1]){
  10. int temp=arr[j];
  11. arr[j]=arr[j+1];
  12. arr[j+1]=temp;
  13. }
  14. }
  15. }
  16. }
  17. }

2.ArrayTest测试类:

  1. public class ArrayTest {
  2. public static void main(String[] args) {
  3. ArrayUtil arrayUtil=new ArrayUtil();
  4. int[] arr=new int[]{12,5,34,89,90,45,36,35,78,44,76,19,-39,0,-98,2};
  5. arrayUtil.sort(arr);
  6. System.out.println("排序后:");
  7. }
  8. }

十二、方法的重载(常用):

1.“两同一不同”:同一个类、相同的方法名
参数列表不同:参数个数不同、参数类型不同、参数顺序不同。
2.判断是否是重载:跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系。
3.在通过对象调用方法时,如何确定某一个指定方法:方法名—->参数列表。
4.System.out.println();方法就是典型的重载方法。

  1. //如下方法构成重载
  2. public void mOL(int i,int j){
  3. }
  4. public void mOL(double i,double j){
  5. }
  6. public void mOL(int i,String j){
  7. }
  8. public void mOL(String j,int i){
  9. }

十三、可变个数形参的方法(一般用在数据库查询):

** 1.可变个数形参的格式:数据类型 … 变量名。
2.当调用可变个数形参方法时,传入的参数个数可以时:0个,1个,2个等等。
3.可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载。
4.可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,两者不能共存
5.可变个数形参在方法的形参中,必须声明在末尾。
6.可变个数形参在方法的形参中,最多只能声明一个可变形参。
总结**:可变个数的形参与数组定义数组相等,所以两者不能共存,数组需要new一个数组,可变个数的形参直接把数值传入即可。可变个数的形参不能定义在已经确定好个数的数据类型前面,因为它是可变的,具有不确定性,编译器无法确定他要传入的可变的参数是几个,所以会报错,但是可变个数的形参可以定义在已经确定好个数的数据类型的后面,因为编译器可以根据他传入的多少而转化成他要的多少。

  1. //如下方法构成重载
  2. public void show(int i){
  3. }
  4. public void show(String s){
  5. }
  6. public void show(String ... s){
  7. }
  8. public void show(int i,String ... s){
  9. }

十四、方法参数的值传递机制(java重点)

1.关于变量的赋值:

  1. 1)如果变量是基本数据类型,此时赋值的是变量所保存的数据值。<br /> 2)如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
  1. public class ValueTransferTest{
  2. public static void main(String[] args) {
  3. System.out.println("***************基本数据类型*****************");
  4. int m=10;
  5. int n=m;
  6. //结果1
  7. System.out.println("m = " + m + ", n = " + n);
  8. n=20;
  9. //结果2
  10. System.out.println("m = " + m + ", n = " + n);
  11. System.out.println("***************引用数据类型*****************");
  12. Order o1=new Order();
  13. o1.orderId=1000;
  14. //赋值以后 o1和o2的地址值相同 都指向了堆空间中同一个对象实体
  15. Order o2=o1;
  16. //结果3
  17. System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " + o2.orderId);
  18. o2.orderId=1500;
  19. //结果4
  20. System.out.println("o1.orderId = " + o1.orderId + ",o2.orderId = " + o2.orderId);
  21. }
  22. }
  23. class Order{
  24. int orderId;
  25. }
  26. //结果1:m=10;n=10 结果2:m=10;n=20
  27. //结果3:o1=1000;o2=1000 结果4:o1=1500;o2=1500

2.方法的形参的传递机制:值传递

(1)定义:
  1. ①形参:方法定义时,声明的小括号内的参数<br /> ②实参:方法调用时,实际传递给形参的数据

(2)值传递机制:
  1. ①如果参数是基本数据类型,此时实参赋给形参的是实参**真实存储的数据值**。<br /> 错误的写法(这个并不能实现交换):
  1. public class ValueTransferTest1 {
  2. public static void main(String[] args) {
  3. int m=10;
  4. int n=20;
  5. System.out.println("m = " + m + ", n = " + n);
  6. //交换两个变量的值的操作
  7. // int temp=m;
  8. // m=n;
  9. // n=temp;
  10. ValueTransferTest1 test1=new ValueTransferTest1();
  11. test1.swap(m,n);
  12. System.out.println("m = " + m + ", n = " + n);
  13. }
  14. public void swap(int m,int n){
  15. int temp=m;
  16. m=n;
  17. n=temp;
  18. }
  19. }
  1. ②如果参数是引用数据类型,此时实参赋给形参的是实参**存储数据的地址值**。<br /> 正确的写法(第一种):
  1. public class ValueTransferTest1 {
  2. public static void main(String[] args) {
  3. Data data=new Data();
  4. data.m=10;
  5. data.n=20;
  6. System.out.println("m = " + data.m + ", n = " + data.n);
  7. //交换m和n的值
  8. int temp=data.m;
  9. data.m=data.n;
  10. data.n=temp;
  11. System.out.println("m = " + data.m + ", n = " + data.n);
  12. }
  13. }
  14. class Data{
  15. int m;
  16. int n;
  17. }
  1. 正确的写法(第二种):<br /> ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1574587/1612687034066-0b58bd4b-381d-41f9-b8b5-10ef3c405fb4.png#align=left&display=inline&height=502&margin=%5Bobject%20Object%5D&name=image.png&originHeight=502&originWidth=641&size=32102&status=done&style=none&width=641)<br /> 代码如下:
  1. public class ValueTransferTest1 {
  2. public static void main(String[] args) {
  3. Data data=new Data();
  4. data.m=10;
  5. data.n=20;
  6. System.out.println("m = " + data.m + ", n = " + data.n);
  7. //交换m和n的值
  8. // int temp=data.m;
  9. // data.m=data.n;
  10. // data.n=temp;
  11. ValueTransferTest1 test1=new ValueTransferTest1();
  12. test1.swap(data);
  13. System.out.println("m = " + data.m + ", n = " + data.n);
  14. }
  15. public void swap(Data data){
  16. int temp=data.m;
  17. data.m=data.n;
  18. data.n=temp;
  19. }
  20. }
  21. class Data{
  22. int m;
  23. int n;
  24. }

注:image.png这个的实例化具体看代码,有static就需要调用对象,两个方法都没有static的话不需要实例化,直接调用方法即可。

题:方法的参数传递的内存分配情况(画出流程图):

  1. public class ValueTransferTest1 {
  2. public static void main(String[] args) {
  3. ValueTransferTest1 test1=new ValueTransferTest1();
  4. test1.first();
  5. }
  6. public void first(){
  7. int i=5;
  8. Value v=new Value();
  9. v.i=25;
  10. second(v,i);
  11. System.out.println(v.i);
  12. }
  13. public void second(Value v,int i){
  14. i=0;
  15. v.i=20;
  16. Value val=new Value();
  17. v=val;
  18. System.out.println(v.i + " " + i);
  19. }
  20. }
  21. class Value{
  22. int i=15;
  23. }

内存分配情况的流程图:
Java面向对象基础 - 图10

十五、递归方法的使用(了解)

1.递归方法:一个方法体内调用它自身。
2.方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

题1:用递归的方法求1-100之间所有自然数的和
  1. public class ValueTransferTest1 {
  2. public static void main(String[] args) {
  3. //计算1-100之间所有自然数的和
  4. //方式一:
  5. //int sum=0;
  6. //for(int i=1;i<=100;i++){
  7. // sum +=i;
  8. // }
  9. ValueTransferTest1 test1=new ValueTransferTest1();
  10. int sum1= test1.getSum(100);
  11. System.out.println(sum1);
  12. }
  13. public int getSum(int n){
  14. if(n==1){
  15. return 1;
  16. }else {
  17. return n + getSum(n-1);
  18. }
  19. }
  20. }

题2:已知有一个数列:f(0)=1,f(1)=4,f(n+2)=2 * f(n+1)+f(n),其中n是大于0的整数,求f(10)的值
  1. public class ValueTransferTest1 {
  2. public static void main(String[] args) {
  3. ValueTransferTest1 test1=new ValueTransferTest1();
  4. int value=test1.f(10);
  5. System.out.println(value);
  6. }
  7. //已知有一个数列:f(0)=1,f(1)=4,f(n+2)=2 * f(n+1)+f(n),其中n是大于0的整数,求f(10)的值
  8. public int f(int n){
  9. if(n==0){
  10. return 1;
  11. }else if (n==1){
  12. return 4;
  13. }else {
  14. return 2 * f(n-1)+f(n-2);
  15. }
  16. }
  17. }

十六、使用形参和实参传递参数的冒泡排序

  1. public class ValueTransferTest1 {
  2. public static void main(String[] args) {
  3. int[] arr=new int[]{23,45,23,1,4,86,30,-46,0,90,43,24,99,44,36,45};
  4. ValueTransferTest1 test1=new ValueTransferTest1();
  5. test1.sort(arr);
  6. System.out.println("排序后:");
  7. }
  8. public void sort(int[] arr){
  9. for (int i=0;i<arr.length;i++){
  10. for (int j=0;j<arr.length-1-i;j++){
  11. if (arr[j]>arr[j+1]){
  12. swap(arr,j,j+1);
  13. }
  14. }
  15. }
  16. }
  17. public void swap(int arr[],int i,int j){
  18. int temp=arr[i];
  19. arr[i]=arr[j];
  20. arr[j]=temp;
  21. }
  22. }

十七、求1-5为半径的分别的圆的面积

  1. 1.Circle类:
  1. public class Circle {
  2. double radius;
  3. //求圆的面积
  4. public double findArea(){
  5. return Math.PI * radius * radius;
  6. }
  7. }

2.PassObject类:

  1. public class PassObject {
  2. public static void main(String[] args) {
  3. PassObject test=new PassObject();
  4. Circle c=new Circle();
  5. test.printAreas(c,5);
  6. System.out.println("now radius is" + c.radius);
  7. }
  8. public void printAreas(Circle c,int time){
  9. System.out.println("Radius\t\tArea");
  10. for (int i=1;i<=time;i++){
  11. //设置圆的半径
  12. c.radius=i;
  13. System.out.println(c.radius + "\t\t" + c.findArea());
  14. }
  15. c.radius=time+1;
  16. }
  17. }

3.结果:
image.png**