国家水资源监控能力建设网站,南沙门户网站建设,做网站php都用什么框架,嘉定网站建设哪里好Java_面向对象
1.面向对象概述
面向对象是一种符合人类思想习惯的编程思想。显示生活中存在各种形态的不同事物#xff0c;这些食物存在着各种各样的联系。在程序中使用对象来映射现实中的事物#xff0c;使用对象的关系来描述事物之间的关系#xff0c;这种思想就是面…Java_面向对象
1.面向对象概述
面向对象是一种符合人类思想习惯的编程思想。显示生活中存在各种形态的不同事物这些食物存在着各种各样的联系。在程序中使用对象来映射现实中的事物使用对象的关系来描述事物之间的关系这种思想就是面向对象的编程思想。使用面向对象思想的编程语言有Java、Python、PHP。。。
与之相对的是面向过程的编程思想面向过程就是分析出解决问题的所需步骤然后用函数把这些步骤一一实现使用的时候依次调用就行了。典型的代表是C语言。
面向对象的三大特征
**封装**将面向对象的核心思想对象的属性和行为封装起来不让外界知道其具体细节**继承**类与类之间的关系通过继承可以通过无需再编写新的类的情况下对原有的类的功能进行扩展多态在一个类中定义的属性和行为被其他类继承后当把子类对象直接赋值给父类引用变量时相同引用类型的变量调用同一个方法所呈现出的多种不同行为特征。
2.Java中的类与对象
**说明**面向对象的编程思想力图让程序中对事物的描述与该事物在现实中的形态保持一致。为了实现这一点面向对象思想中提出了两个概念----类与对象。
**类**是一类事物的描述包含属性和行为。如动物类、汽车类…**对象**某一类事物的具体体现。如动物类的、、、等汽车类的、、、等。
2.1.类
面向对象的核心思想是对象但要创建对象首先需要定义一个类。类是对象的抽象用于描述一组对象的共同行为特征。以面向对象的思想就可以将某一类中共同的特征和行为封装起来把共同的特征作为类的属性也叫成员变量把共同行为作为类的方法也叫成员方法。
定义类 public class 类名 {// 成员变量// 成员方法
}public class Person {// 成员变量:描述类的属性String name; // 人的姓名int age; // 人的年龄/** 成员方法* 格式权限修饰符 返回值类型 方法名(args...) {方法体 return 返回值}* */// 吃饭的方法public void eat(String food) {System.out.println(name 正在吃 food);}// 睡觉的方法public void sleep() {System.out.println(name 正在睡觉);}
}2.2.对象
对象是类的具体体现。要使用一个类必须通过对象来实现创建对象的语法格式为
类名 对象名 new 类名();Person p new Person();/*
* 通过Person类创建对象
* */
public class Object {public static void main(String[] args) {// 1.创建对象Person p new Person();// 2.使用成员变量--对象名.变量名System.out.println(p.name); // nullSystem.out.println(p.age); // 0// 赋值p.name 张三;p.age 20;System.out.println();// 3.使用成员方法--对象名.方法名()p.eat(西瓜);p.sleep();}
}其对象的内存示意图为 代码执行流程为
Person类和Object类的字节码文件加载到方法区找到主方法main()进入到栈空间并创建对象p一切new关键字的对象进入堆内存并引入属性和方法先执行eat()方法执行完毕被销毁再执行sleep()方法执行完毕也随之销毁main()方法随着程序执行完成也随之销毁。
注意
程序执行完毕垃圾将会被回收。回收的条件是引用计数器是否为0。方法进入栈中采用“先来后出”的方式这一过程被称为《压栈》。
2.3.对象的比较
在Java中有两种对象的比较方式分为为“”运算符和equals()方法这两种方式有着本质的区别以下面例子说明
我们创建Compare类
public class ObjCompare {public static void main(String[] args) {// 创建两个String对象引用String c1 new String(abc);String c2 new String(abc);String c3 c1;// 使用运算符比较System.out.println(c2c3的结果为 (c2c3));// 使用equals()方法比较System.out.println(c2.equals(c3)的结果为 (c2.equals(c3)));}
} 运行结果为 从上述运行结果中可以看出“”运算符和equals()方法比较的结果是不同的。**equals()方法是String类中的方法它用于比较两个对象引用所指的内容是否相等而“”运算符比较的是两个对象引用的地址是否相等。**由于c1和c2是两个不同对象引用两者在内存中的位置不同而String c3 c1;语句将c1的引用赋给c3所以c1和c3这两个对象的引用是相等的也就是打印c1c3将返回true。它们的内存引用如下图 2.4.局部变量和成员变量
在类中定义的变量为成员变量全局变量在方法中定义的变量为局部变量。Java遵守就近原则谁离得近就优先使用谁。
我们在eat()方法中新增属性String name 李四;这时执行的是“李四正在吃xx”
// 吃饭的方法
public void eat(String food) {String name 李四;System.out.println(name 正在吃 food);}成员变量和局部变量的区别
定义位置 成员变量定义在类中方法外局部变量定义在方法内部 内存中的位置 成员变量在堆内存中局部变量在栈内存中 声明周期的区别 成员变量随着对象的创建而创建随着对象的消失而消失局部变量随着方法的调用而创建随着方法的消失而消失 默认初始化值的区别 成员变量有默认初始化值局部变量没有默认初始化值使用之前必须赋值
2.5.访问修饰符
在Java中针对类和对象提供了四种访问级别分别是privatedefaultprotected和public。它们的访问控制级别由小到大为 四种访问级别说明
**private(当前类访问级别)**如果类的成员被private访问控制符来修饰则这个成员只能被该类的其他成员访问其他类无法直接访问。类的良好封装就是通过private来实现的。**default(包访问级别)**如果一个类或者类的成员不适用任何访问控制符修饰则称它为默认访问控制级别这个类或者类的成员只能被本包中的其他类访问。**protected(子类访问级别)**如果一个类成员被protected访问控制符修饰那么这个成员就能被同一包下的其他类访问也能被不同包下的该类的子类访问。**public(公共访问级别)**这是一个最宽松的访问控制级别如果一个类或者类的成员被public访问控制符修饰那么这个类或者类的成员能被所有的类访问不过访问类和被访问类是否在同一个包中。 3.类的封装
封装是面向对象的核心思想。将对象的属性和行为封装起来其载体就是类类通常对客户隐藏其实现细节这就是封装思想。例如用户使用计算机只需要使用手指敲击键盘就可以实现一些功能无需知道计算机内部是如何工作的。即使知道计算机工作的原理但在使用计算机时也并不依赖计算机工作原理这些细节。
采用封装思想保证了类内部数据结构的完整性应用该类的用户不能轻易地直接操作此数据结构只能执行类允许公开的数据。这样避免了外部操作对内部数据的影响提高了程序的可维护性。 假如我们利用上面创建的Person类再创建一个Demo类来测试
public class Demo {public static void main(String[] args) {Person p new Person();p.name 张三;p.age -123;System.out.println(姓名是 p.name 年龄是 p.age );}
} 我们可以发现我们创建的这个Demo类随意设置了数据且有些数据是不合理的。那么我们就应该封装Person类提高代码的可维护性。使用修饰符private就可以实现对类成员的封装
private String name; // 人的姓名
private int age; // 人的年龄 经过private封装后的属性我们看到在本类中使用是没有问题的但在Demo类中就报错了 想要实现访问这两个属性我们需要增加一个访问这两个属性的公共方法这样Demo类就可以通过这个公共方法实现属性的访问。
// 设置值
public void setName(String n) {name n;
}
// 获取值
public String getName() {return name;
}
// 设置值public void setAge(String a) {if (a 0 || a 200) {System.out.println(你设置的年龄不合法);}else {age a;}
}
// 获取值
public String getAge() {return age;
} 这是我们就可以在Demo类中通过get和set方法就可以设置值和访问值了
public class Demo {public static void main(String[] args) {Person p new Person();// 设置值p.setName(张三);p.setAge(123);// 获取值String name p.getName();int age p.getAge();System.out.println(姓名是 name 年龄是 age );}
}4.方法的重载和递归
重载就是函数或方法有相同的名称但是参数列表不相同的情形。这样同名不同参数的函数或者参数之间互相称之为重载。通俗理解就是省了给method重新命名了差不多都用同一个。
而递归则是因特殊业务需求需要在函数内部调用自己的过程这样能做到“大事化小小事化了”。 需要注意的是递归必须要有结束的条件不然就会陷入无限的递归状态永远无法结束调用。
重载实例
public class Overload {public static void main(String[] args) {int sum getSum(20,30);int sum01 getSum(20,30,40);System.out.println(sum);System.out.println(sum01);}/*** 定义求两个整数和的方法* 明确参数int num01, int num02* 返回值int* */public static int getSum(int num01,int num02) {int sum num01 num02;return sum;}/*** 求三个数和的方法* 参数:int num01,int num02,int num03* 返回值int*/public static int getSum(int num01,int num02,int num03) {int sum num01 num02 num03;return sum;}
}递归实例
public class Recursion {public static void main(String[] args) {int sum getSum(5);System.out.println(sum);}/*** 需求求5-1之间的数字之和* 54321* 5(4-1之间的和) 4(3-1之间的和)...*/public static int getSum(int num) {if (num 1) {return 1;}return num getSum(num-1);}
}练习递归读取指定文件夹下的文件和目录
public class Test1 {public static void showDirectory(File file) {File[] filesfile.listFiles();for(File a:files) {System.out.println(a.getAbsolutePath());if(a.isDirectory()) {try{showDirectory(a);}catch (Exception e) {System.out.println(e);}}}}public static void main(String[] args) {File filenew File(D:\\);showDirectory(file);}
}5.构造方法
实例化一个对象后如果要为这个对象中的属性赋值则必须通过直接访问对象的属性或调用setXXX()方法的方式才可以。如果需要在实例化对象的同时就为这个对象的属性进行赋值则可以通过构造方法来实现。
**构造方法**是类的一个特殊成员它会在类实例化对象时被自动调用。以之前的Person类为例我们只需要在你们去添加无参构造和有参构造就可以在实例化对象时初始化一些值。
// 无参构造
public Person() {}
// 有参构造
public Person(String name, int age) {this.name name;this.age age;
} 我们可以看到构造方法就是直接以类名作为方法名根据参数的不同分为无参构造和有参构造。通过这两个不同的构造方法创建出来的对象也是不同的
Person p1 new Person(); // 无参构造创建对象
Person p2 new Person(张三,20); // 有参构造创建对象 关于构造方法有几个注意事项
构造方法和类名一致构造方法没有返回值类型void也不需要写构造方法中不能写return语句每一个类都有一个默认的无参构造所以可以不用手动写出来。
6.this关键字
在有参构造中我们看到了this关键字的使用这是因为要将参数和属性进行统一命名见名知义保持程序的可读性但如果没有就会产生成员变量和局部变量的命名冲突在方法中无法访问成员变量。所以Java提供了this来指代当前对象用于在方法中访问对象的其他成员。
7.static关键字
有时候在处理问题时需要两个类在同一个内存区域共享一个数据。例如在球类中PI这个常量可能除了本类需要这个常量外在另一个圆类中也需要这个常量。这时没有必要再两个类中同时创建PI常量因为这样系统会将两个不在同一个类中定义的常量分配到不同的内存空间中。为了解决这个问题可以将这个常量设置未静态的。PI常量在内存中被共享的布局如图所示 被生命static的变量、常量、方法被称为静态成员。静态成员属于类所有区别于个别对象可以在本类后者其他类使用类名和.调用静态成员。语法如下
类名.静态成员 在下面代码中创建了StaticTest类该类中的主方法调用静态成员并在控制台输出。
// 静态方法的调用
public class StaticTest {final static double PI 3.1415; // 定义静态常量static int id; // 定义静态变量public static void method1() {// do Something}public void method2() {System.out.println(StaticTest.PI);System.out.println(StaticTest.id);StaticTest.method1();}
} 静态方法也可以通过对象.的方式但不推荐这种用法以便和非静态成员分开。
静态数据与静态方法的作用通常是为了提供共享数据或方法如数学计算公式等以static生命并实现这样当需要使用时直接使用类名调用这些静态成员即可。机关使用这种方式调用静态成员比较方便但静态成员同样遵循public,private,protected修饰符的约束。
在StaticTest类中创建书方法调用静态成员并输出
public class StaticTest {final static double PI 3.1415; // 定义静态常量static int id; // 定义静态变量public static void method1() {// do Something}public void method2() {System.out.println(StaticTest.PI);System.out.println(StaticTest.id);StaticTest.method1();}public static StaticTest method3() {method2(); // 调用非静态方法return this;}
} 我们会发现以上代码会报错这是因为在静态方法中调用了非静态方法和this关键字的出现在Java中有两点规定
在静态方法中不可以使用this关键字在静态方法中不可以直接调用非静态方法。
**注意**在Java中规定不能将方法体内的局部变量声明为static的。例如下面代码就是错误的
public class example{puclic void method() {static int i 0;}}**技巧**如果在执行类时希望先执行类的初始化操作可以使用static定义一个静态区域例如如下代码当这段代码执行时首先执行static块中的程序并且只会执行一次
public class example {static {// }}静态代码块练习
public class Demo04 {static {System.out.println(我是静态代码块。。。);}
}public class Demo05 {public static void main(String[] args) {Demo04 d new Demo04();Demo04 d1 new Demo04();}
} 我们发现创建对象就执行了静态代码块且执行一次。
静态变量的练习创建Student类有name、age、schoolName三个属性在Demo类中分别创建三个对象使得他们姓名、年龄不同但学校相同既可以使用静态变量占用一个内存
public class Student {private String name; // 姓名private int age; // 年龄private String schoolName; // 大学名称Overridepublic String toString() {return Student{ name name \ , age age , schoolName schoolName \ };}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}public String getSchoolName() {return schoolName;}public void setSchoolName(String schoolName) {this.schoolName schoolName;}
}
public class Demo01 {public static void main(String[] args) {Student s01 new Student();s01.setName(张三);s01.setAge(20);s01.setSchoolName(四川城市职业学院);System.out.println(s01);System.out.println();Student s02 new Student();s02.setName(李四);s02.setAge(21);s02.setSchoolName(四川城市职业学院);System.out.println(s02);System.out.println();Student s03 new Student();s03.setName(王五);s03.setAge(20);s03.setSchoolName(四川城市职业学院);System.out.println(s03);}
} 以上代码我们发现他们三个对象都一个同一变量值为“四川城市职业学院”如果创建三个对象对应在内存中也要为这个值开辟三个空间这样浪费了内存我们可以将schoolName声明为静态变量这样一个对象赋值其他对象也可以一并使用了
// 将Student类的schoolName变为静态变量
private static String schoolName;// 注释Demo01中s02和s03对schoolName属性的赋值
// s02.setSchoolName(四川城市职业学院);
// s03.setSchoolName(四川城市职业学院); 运行发现实现了静态变量的共享 ); System.out.println(“”); Student s03 new Student();s03.setName(王五);s03.setAge(20);s03.setSchoolName(四川城市职业学院);System.out.println(s03);
}} 以上代码我们发现他们三个对象都一个同一变量值为“四川城市职业学院”如果创建三个对象对应在内存中也要为这个值开辟三个空间这样浪费了内存我们可以将schoolName声明为静态变量这样一个对象赋值其他对象也可以一并使用了java
// 将Student类的schoolName变为静态变量
private static String schoolName;// 注释Demo01中s02和s03对schoolName属性的赋值
// s02.setSchoolName(四川城市职业学院);
// s03.setSchoolName(四川城市职业学院); 运行发现实现了静态变量的共享
[外链图片转存中…(img-p29C2KQe-1677763476620)]