Java编程 面向对象详讲
面向对象上篇*
## 1.类与对象
1.1看一个养猫猫问题
1.2 java语言是面向对象的
计算机语言的发展向接近人的思维方式演变(能编写功能更多软件):
汇编语言 [面向机器] 有助记符 load return …
c语言 [面向过程] 函数=> 完成功能
java语言 [面向对象] 类与对象 => 编写更加复杂,大型软件
汇编语言(汇编 不会编,不会编汇编)=> 驱动程序
1.3类与对象的关系示意图
1.4 快速入门-面向对象的方式解决养猫问题
import java.util.Scanner;
public class OOPTest
{
public static void main(String[] args) {
// int num1 = 20;
Cat cat1 = new Cat();
cat1.name = "小白";
cat1.age = 3;
cat1.color = "白色";
System.out.println("猫的信息:" + cat1.name + " " + cat1.age + " " + cat1.color);
}
}
//定义一个猫类(数据类型)
class Cat //Cat.class
{
//属性
String name; // null
int age;//0
String color;//null
//行为 =》 方法
}
class Car
{
//属性,成员变量,字段
String name;
double price;
String color;
}
1.5类和对象的区别和联系
通过上面的案例和讲解我们可以看出:
1)类是抽象的,概念的,代表一类事物,比如人类,猫类…, 即它是数据类型.
2)对象是具体的,实际的,代表一个具体事物, 即 是实例.
3)类是对象的模板,对象是类的一个个体,对应一个实例
1.6对象在内存中存在的形式
1.7属性/成员变量
基本介绍
1)从概念或叫法上看: 成员变量 = 属性 = field (即 成员变量是用来表示属性的,授课中,统一叫 属性)
案例演示:Car(name,price,color)
2)属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)。比如我们前面定义猫类 的 int age 就是属性
属性的注意事项和细节
import java.util.Scanner;
public class ProDetail
{
public static void main(String[] args) {
int num = 100;
/*
属性如果不赋值,有默认值,规则和数组一致。
案例演示:[Cat, Dog] //int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,
boolean false,String null , 即只有是引用类型,统统为null
*/
Cat myCat = new Cat();
System.out.println("默认值 " + myCat.name + " " + myCat.age + " " + myCat.color);
Cat myCat2 = new Cat();
myCat2.name = "小白";
System.out.println("mycat " + myCat.name + " " + myCat.age + " " + myCat.color);
System.out.println("mycat2 " + myCat2.name + " " + myCat2.age + " " + myCat2.color);
}
}
//定义一个猫类(数据类型)
class Cat
{
//属性
String name;
int age;
String color;
//行为 =》 方法
}
1.8类和对象的内存分配机制(重要)
1.9Java内存的结构分析
1)栈: 一般存放基本数据类型(局部变量)
2)堆: 存放对象(Cat cat , 数组等)
3)方法区:常量池(常量,比如字符串), 类加载信息
4)示意图 [Cat (name, age, price)]
1.10java创建对象的流程简单分析
1)先加载Person 类 , 只会加载一次
2)在堆中,分配空间[地址],并进行默认初始化,比如 name=null age = 0
3)把堆中地址,返回给 p1
4)进行指定初始化 name = “jack” age = 10
5)开始使用p1
1.11类和对象的内存分配机制-练习题
2成员方法
2.1基本介绍
在某些情况下,我们要需要定义成员方法。比如人类:除了有一些属性外( 年龄,姓名…),我们人类还有一些行为比如:可以说话、跑步…,通过学习,我们人类还可以做算术题。这时就要用成员方法才能完成。现在要求对Cat类完善。
2.2成员方法快速入门
1)添加speak 成员方法,输出 我是一只好猫
2)添加jisuan 成员方法,可以计算从 1+…+1000的结果
3)添加cal 成员方法,该方法可以接收一个数n,计算从 1+…+n 的结果
4)添加getSum成员方法,可以计算两个数的和
5)代码:
import java.util.Scanner;
//成员方法的使用
public class MethodTest
{
public static void main(String[] args) {
//调用方法
//1. 创建对象
Cat myCat = new Cat();
//2. 调用方法
myCat.speak();
myCat.jisuan();
System.out.println("请输入一个整数");
Scanner myScanner = new Scanner(System.in);
int num = myScanner.nextInt();
myCat.cal(num); // 20 称为 实际参数(实参)
myCat.getSum(30, 100);
}
}
//定义一个猫类(数据类型)
class Cat //Cat.class
{
//属性
String name; // null
int age;//0
String color;//null
//行为 =》 方法
//添加speak 成员方法,输出 我是一只好猫
//解读
//1. public 表示公开方法
//2. void 没有返回值
//3. speak 方法名, () 没有形参
//4 { } 称为方法体
//5. 写入你的代码
public void speak() {
System.out.println("我是一只好猫");
}
//添加jisuan 成员方法,可以计算从 1+..+1000的结果
public void jisuan() {
int sum = 0;
for( int i = 1; i <= 1000; i++) {
sum += i;
}
System.out.println("sum=" + sum);
}
//传递参数
//添加cal 成员方法,该方法可以接收一个数n,计算从 1+..+n 的结果
//传递参数
//术语 :int n 称为 形式参数(形参)
public void cal(int n) {
int sum = 0;
for( int i = 1; i <= n; i++) {
sum += i;
}
System.out.println("sum=" + sum);
}
//添加getSum成员方法,可以计算两个数的和
public void getSum(int n1, int n2) {
int sum = n1 + n2;
System.out.println("和=" + sum);
}
}
2.3方法的调用机制原理:(重要!!!)
提示:画出程序执行过程[cal]+说明
2.4为什么需要成员方法
看一个需求:
请遍历一个数组 , 输出数组的各个元素值。
解决思路1,传统的方法,就是使用单个for循环,将数组输出,大家看看问题是什么?
解决思路2: 定义一个类 MyTools ,然后写一个成员方法,看看效果又如何。
代码如下
import java.util.Scanner;
//成员方法的使用
public class WhyMethod
{
public static void main(String[] args) {
int[] arr1 = {1, 2, 50, 900, 900, -12};
//创建MyTools对象
MyTools tools = new MyTools();
tools.printArr(arr1);
int[] arr2 = {1, 2, 50, 900, 900, -12, 10000};
tools.printArr(arr2);
int[] arr3 = {1, 2, 50, 900, 900};
tools.printArr(arr3);
}
}
class MyTools //工具类
{
public void printArr(int[] arr) { //方法
System.out.println();
for( int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ", ");
}
}
}
2.5成员方法的好处
1)提高代码的复用性
2)可以将实现的细节封装起来,然后供其他用户来调用即可。!!!
2.6成员方法的定义
2.7注意事项和使用细节
修饰符 (作用是控制 方法使用的范围)
可选,如果不写就是默认的 [public > protected > 默认 > private], 具体在后面说
返回类型
1)一个方法至多有一个返回值 [思考,如何返回多个结果, 数组]
2)返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
3)如果方法有返回值,则方法体中最后的执行语句必须为return语句,而且要求返回类型必须和return的值类型一致或兼容
4)如果方法没有返回值,则方法体中可以没有return语句,返回类型要求写void
方法名
遵循驼峰命名法,最好见名知义,表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规范
参数列表
-
一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开(类型 名,类型 名) 【getMax , 比如得到三个数的最大值 】
-
参数类型可以为任意类型,包含基本类型或引用类型 【test100】
-
调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型 的参数!【test200】
4)方法定义时的参数称为形式参数,简称形参;方法调用时的参数称为实际参数,简称实参,实参和形参的类型(兼容)、个数、顺序必须一致!
方法体
里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即:方法不能嵌套定义。[test400]
成员方法的调用说明 -
同一个类中的方法调用:直接调用即可。比如 print(参数);
案例演示:A类 sayOk 调用 print() -
跨类中的方法A类调用B类方法:需要通过对象名调用。比如 对象名.方法名(参数); 案例演示:B类 sayHello 调用 print()
代码
import java.util.Scanner;
public class MethodDetail
{
public static void main(String[] args) {
//一个方法至多有一个返回值 [思考,如何返回多个结果, 数组.]
//创建对象
Cat myCat = new Cat();
//解读
//1. myCat.m1(4) 返回一个int 结果
int res = myCat.m1(5);
System.out.println("res=" + res);
//2. 测试数组
// myCat.m2(1, 4) 返回一个数组
int[] reses = myCat.m2(1, 4);
System.out.println("和=" + reses[0]);
System.out.println("差=" + reses[1]);
//public void m6(int n1, double d1, int[] arr)
int[] arr = {};
myCat.m6(10, 1, arr);
//测试
A aObj = new A();
aObj.sayOk();
}
}
class B
{
public void sayHello() {
//需要通过对象名调用
A aObj = new A();
aObj.sayHi();
}
}
class A
{
//同一个类中的方法调用:直接调用即可
public void sayHi() {
System.out.println("say hi");
}
public void sayOk() {
sayHi();
System.out.println("say ok");
}
}
class Cat
{
//一个方法至多有一个返回值 [思考,如何返回多个结果, 数组.]
public int m1(int n) {
return 2 * n;
}
public int[] m2(int n1, int n2) {
//创建一个数组
int[] res = new int[2];
res[0] = n1 + n2;
res[1] = n1 - n2;
return res;
}
//如果方法有返回值,则方法体中最后的执行语句必须为return语句,
//而且要求返回类型必须和return的值类型一致或兼容
public int m3() {
return (int)1.1;
}
//如果方法没有返回值,则方法体中可以没有return语句,返回类型要求写void
public void m4() {
}
//参数类型可以为任意类型,包含基本类型或引用类型
public void m5(int n, int[] arr) {
}
//调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型 的参数!
public void m6(int n1, double d1, int[] arr) {
//方法体.
//调用其他方法...
}
//方法不能嵌套定义
public void m7() {
// public void m8() {
//
// }
}
}
3 成员方法传参机制
3.1基本数据类型的传参机制
看一个案例
编写一个方法,交换两个整数的值。
import java.util.Scanner;
//基本数据类型传递
public class MethodPassPara01
{
public static void main(String[] args) {
T2 t2 = new T2();
int a = 30;
int b = 50;
t2.swap(a, b);
System.out.printf("a=%d b=%d\n", a, b);
}
}
class T2
{
public void swap( int num1, int num2) {
System.out.println("swap方法中...");
System.out.printf("num1=%d num2=%d\n", num1, num2);
int temp = 0;
temp = num1;
num1 = num2;
num2 = temp;
System.out.printf("num1=%d num2=%d\n", num1, num2);
}
}
- 结论及示意图 基本数据类型,传递的是值(元素内容, 值拷贝), 形参的任何改变不影响实参!
- 示意图
3.2引用数据类型的传参机制
- 看一个案例
B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?
B类中编写一个方法test200,可以接收一个Person(age,sal)对象,在方法中修改该对象属性,看看原来的对象是否变化?
import java.util.Scanner;
//基本数据类型传递
public class MethodPassPara02
{
public static void main(String[] args) {
int[] arr = {1,2,3};
T3 t3 = new T3();
t3.test100(arr);
//看看 arr 的情况
for( int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
class T3
{
public void test100(int[] arr ) {
arr[0] = 100;
}
}
结论及示意图
引用类型传递的是值(地址),可以通过形参影响实参!
- 再看一个案例,下面的方法会对原来的对象有影响吗?
p=null 和 p = new Person(); 对应示意图
import java.util.Scanner;
//基本数据类型传递
public class MethodPassParaExer01
{
public static void main(String[] args) {
Person p = new Person();
p.name = "tom";
p.age = 12;
T5 t5 = new T5();
//t5.m1(p);
//t5.m2(p);
t5.m3(p);
System.out.println(p.name + " " + p.age);// tom, 12
}
}
class Person
{
String name;
int age;
}
class T5
{
public void m3(Person p) {
p = new Person();
p.age = 500;
}
public void m1(Person p) {
p.age = 100;
}
public void m2(Person p) {
p = null;
}
}
3.3成员方法返回类型是引用类型应用实例
先练习
1)编写类MyTools类,编写一个方法可以打印二维数组的数据。
2)编写一个方法copyArray,可以复制一个数组,返回复制的数组。
扩展:可以接收一个参数,指定拷贝原数组的多少个元素。
比如:{1,2, 0, 78, 999}
3)编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。克隆对象。。, 注意得到新对象和原来的对象是两个独立的对象,只是他们的属性相同
代码
import java.util.Scanner;
//基本数据类型传递
public class MethodPassParaExer02
{
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
MyTools mt = new MyTools();
int[] arrNew = mt.copyArray(arr, -1);
for( int i = 0; i < arrNew.length; i++) {
System.out.print(arrNew[i] + "\t");
}
}
}
class Person
{
String name;
int age;
}
//编写类MyTools类,编写一个方法可以打印二维数组的数据
class MyTools
{
public void printArr(int[][] arr) {
for( int i = 0; i < arr.length; i++) {
for( int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
}
//编写一个方法copyArray,可以复制一个数组,返回复制的数组
//扩展:可以接收一个参数,指定拷贝原数组的多少个元素
public int[] copyArray(int[] arr, int size) {
//求出实际应该拷贝几个元素
//程序员 你想如何处理....
int len = size > arr.length || size <=0 ? arr.length : size;
// int[] arrNew = new int[arr.length];
int[] arrNew = new int[len];
for( int i = 0; i < len; i++) {
arrNew[i] = arr[i];
}
return arrNew;
}
//拷贝一个Person
public Person copyPerson(Person p) {
//创建一个新人
Person newPerson = new Person();
newPerson.name = p.name;
newPerson.age = p.age;
return newPerson;
}
}
补充:public 类也可以写方法,并在 main 创建对象,调用方法
import java.util.Scanner;
//基本数据类型传递
public class ObjectUse //类
{
public static void main(String[] args) {
//使用
ObjectUse ou = new ObjectUse();
ou.sayHi();
}
//方法
public void sayHi() {
System.out.println("say hi");
}
public void sayOk() {
sayHi();
}
}
4方法的重载(OverLoad)
4.1基本介绍
java中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!
比如:System.out.println(); out是PrintStream类型
4.2重载的好处
1)减轻了起名的麻烦
2)减轻了记名的麻烦
4.3重载的快速入门案例
看一个案例
【要求:类名MyPrint,方法名为print,可以打印 等边三角形,矩形,立方体。示意】
public class OverLoadTest
{
public static void main(String[] args) {
MyPrint mp = new MyPrint();
mp.print(10);
mp.print(1, 2, 3);
}
}
//要求:类名MyPrint,方法名为print,可以打印 等边三角形,矩形,立方体。示意
class MyPrint {
public void print(int len) {
System.out.println("打印 等边三角形 边长=" + len);
}
public void print(int len, int width) {
System.out.println("打印 矩形 长=" + len + " 宽=" + width);
}
public void print(int len, int width, int height) {
System.out.println("打印 立方体 长=" + len + " 宽=" + width + " 高=" + height);
}
}
4.4注意事项和使用细节
1)方法名 :必须相同
2)参数列表:必须不同(参数类型或个数或顺序,至少有一样不同,参数名无要求)
3)返回类型:无要求
案例:类:MyCalculator 方法:calculate
calculate(int n1, int n2)
calculate(int n1, double n2)
calculate(double n2, int n1)
calculate(int n1, int n2,int n3)
5 可变参数
5.1基本概念
jdk5.0出现的新特性,java提供了一种机制,可以允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
5.2基本语法
访问修饰符 返回类型 方法名(数据类型… 形参名){
}
5.3快速入门案例(VarArgusDemo.java)
看一个案例 类 MethodUtils,方法 sum 【可以计算 2个数的和,3个数的和 , 4. 5, 。。】
utils 工具集
代码
//演示可变参数使用
public class VarArgs
{
public static void main(String[] args) {
VarArgs va = new VarArgs();
double res1 = va.sum(1, 2, 3, 9, 1.1);
System.out.println("res1=" + res1);
double[] arr = {1,2,4};
double res2 = va.sum(arr);
}
//演示可变参数使用
//说明
//1. double... 后面的三个小点,是规定
//2. 这时 args 称为 可变形参
//3. args 可变形参的本质就是数组
//4. 实参可以传递数组,但是需要通过 数组名
//5. 不能在定义 sum(double[] arr), 会认为重复定义
public double sum(double... args) {
double totalSum = 0.0;
for( int i = 0; i < args.length; i++) {
totalSum += args[i];
}
return totalSum;
}
}
5.4注意事项和细节
1)可变参数的实参可以为0个或任意多个。
2)可变参数的实参可以为数组。
3)可变参数的本质就是数组.
4)可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
5)一个形参列表中只能出现一个可变参数
6)代码
//演示可变参数使用
public class VarArgsDetail
{
public static void main(String[] args) {
VarArgs va = new VarArgs();
//细节1: 可变参数的实参可以为0个或任意多个
va.sum();
//可变参数的实参可以为数组
double[] arr = {1,2,4};
double res2 = va.sum(arr);
}
//可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
public void m1(String name, String... args) {
}
//一个形参列表中只能出现一个可变参数
// public void m2(int... args1 , String... args2) {
//
// }
//演示可变参数使用
//说明
//1. double... 后面的三个小点,是规定
//2. 这时 args 称为 可变形参
//3. args 可变形参的本质就是数组
//4. 实参可以传递数组,但是需要通过 数组名
//5. 不能在定义 sum(double[] arr), 会认为重复定义
public double sum(double... args) {
double totalSum = 0.0;
for( int i = 0; i < args.length; i++) {
totalSum += args[i];
}
return totalSum;
}
}
6创建Java自定义类步骤总结(OOP(oriented[面向] object[对象] programming[编程]))
**
6.1步骤
1)定义类,确定类名
2)编写类的属性
3)编写类的方法
4)创建对象,使用方法。
~~**自己先练习,后面有代码示例 具体问本人 本人QQ:825794519
还有韩顺平老师的java原视频**~~
import java.util.Scanner;
public class BoxExer
{
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
Box box = new Box();
System.out.println("长");
box.len = myScanner.nextDouble();
System.out.println("宽");
box.width = myScanner.nextDouble();
System.out.println("高");
box.height = myScanner.nextDouble();
System.out.println("体积=" + box.volume());
}
}
/*
编程创建一个Box类,在其中定义三个属性表示一个立方体的长、宽和高,长宽高可以通过控制台输入。
定义一个方法获取立方体的体积(volume)。
创建一个对象,打印给定尺寸的立方体的体积
*/
class Box
{
double len;
double width;
double height;
public double volume() {
return len * width * height;
}
}
6.2景区门票案例
1)一个景区根据游人的年龄收取不同价格的门票。
2)请编写游人类,根据年龄段决定能够购买的门票价格并输出
3)规则:年龄>18 , 门票为20元,其它情况免费。
4)可以循环从控制台输入名字和年龄,打印门票收费情况, 如果名字输入 n ,则退出程序。
5)代码
import java.util.Scanner;
//游客
public class VisitorExer
{
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
//得到年龄
do
{
//创建一个游客
Visitor v = new Visitor();
System.out.println("姓名:");
v.name = myScanner.next();
if( "n".equals(v.name)) {
break;
}
System.out.println("年龄:");
v.age = myScanner.nextInt();
//计算
v.ticketMoney();
//显示
v.showInfo();
}while (true);
}
}
/*
1.一个景区根据游人的年龄收取不同价格的门票。
2.请编写游人类,根据年龄段决定能够购买的门票价格并输出
3.规则:年龄>18 , 门票为20元,其它情况免费。
4.可以循环从控制台输入名字和年龄,打印门票收费情况, 如果名字输入 n ,则退出程序。
*/
class Visitor
{
String name; //名字
int age; //年龄
double payMoney;//应付
//写一个方法,得到应付
public void ticketMoney() {
//规则:年龄>18 , 门票为20元,其它情况免费
if(age > 18) {
payMoney = 20;
}
}
//显示方法
public void showInfo() {
if(payMoney != 0) {
System.out.println(name+ " 年龄是" + age + " 应付票价" + payMoney);
} else {
System.out.println(name+ " 年龄是" + age + " 免费");
}
}
}
7属性和局部变量作用域
7.1基本使用
1)面向对象中,变量作用域是非常重要知识点,相对来说不是特别好理解,请大家注意听,认真思考,要求深刻掌握变量作用域。
2)在java编程中,主要的变量就是属性(成员变量)和局部变量。A类:sum
3)我们说的局部变量一般是指在成员方法中定义的变量。【举例】
4)java中作用域的分类
全局变量:也就是属性,作用域为整个类体 A类:sum sub 等方法使用属性 【举例】
局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!
5)全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值。[举例]
7.2注意事项和细节使用
1)属性全局变量和局部变量可以重名,访问时遵循就近原则。
2)在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。[举例]
3)全局变量,存储在堆中。局部变量,存储在栈中,需要画一个示意图说明。【重要】
4)全局变量,生命周期较长,伴随着对象的创建而创建,伴随着对象的死亡而死亡。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而死亡。即在一次方法调用过程中。【每调用一次方法,就开一个方法栈,这个是由操作系统决定的】
5)作用域不同
全局变量:可以被本类使用,或其他类使用(通过对象调用)
局部变量:只能在本类中对应的方法中的作用域内使用
6)修饰符不同
全局变量/属性可以加修饰符
局部变量不可以加修饰符
7)特别说明: 如果我们在方法中,是new 对象,比如 Person p = new Person();
p在方法中, 对象数据空间在堆中…, 如果p 没有返回,则方法结束后,对象成为垃圾,被回收,如果返回给 其它方法,比如main , 则可以继续使用
import java.util.Scanner;
//游客
public class VarScopeTest
{
public static void main(String[] args) {
}
}
class A {
int num = 10;//属性
int age; //默认0
public void m1() {
int total = 30; //局部变量
System.out.println(num);
}
public void m2() {
//不能使用total
System.out.println(num);
}
public void m3() {
//全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值
System.out.println(age);
int personNum = 9; //局部变量
System.out.println(personNum);
}
}
8构造方法
8.1看一个需求
我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做? 这时就可以使用构造方法/构造器。
8.2基本语法
[修饰符] 方法名(参数列表){
构造方法体
}
说明:
1)构造器的修饰符可以默认
2)构造器没有返回值
3)方法名 和类名字必须一样
4)参数列表 和 成员方法一样的规则
5)构造器的调用有系统JVM 来调用
8.3基本介绍
构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点:
1)方法名和类名相同
2)没有返回值
3)在创建一个类的新对象时,系统会自动的调用该类的构造方法完成对新对象的初始化。
8.4快速入门
现在我们就用构造方法来完成刚才提出的问题:在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做?
代码
import java.util.Scanner;
//游客
public class ConTest
{
public static void main(String[] args) {
//传统写法
// Person p1 = new Person();
// p1.name = "jack";
// p1.age = 20;
//构造器
Person p2 = new Person("tom", 30);
System.out.println(p2.name + " " + p2.age);
}
}
class Person
{
String name;
int age;
//构造器
public Person(String pName, int pAge) {
System.out.println("构造器被调用....");
name = pName;
age = pAge;
}
}
8.5注意事项和使用细节
1)一个类可以定义多个不同的构造方法,构造方法重载
比如:我们可以再给Person类定义一个构造方法,用该方法来创建新对象的时候,只指定人名,不需要指定年龄。
2)构造方法名和类名相同
3)构造方法没有返回值
4)主要作用是完成对新对象的初始化, 并不是创建对象
5)在创建新对象时,系统自动的调用该类的构造方法
6)如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),比如 Person (){}
7)一旦定义了自己的构造方法,默认的构造方法就覆盖了,就不能再使用默认的无参构造方法,除非显示的定义一下,即: Person(){};
8)代码
import java.util.Scanner;
//游客
public class ConDetail
{
public static void main(String[] args) {
new Dog("旺财");
new Person();
}
}
//如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),
//比如 Person (){}
class Person {
//默认的一个无参构造器
//一旦定义了自己的构造方法,默认的构造方法就覆盖了,
//就不能再使用默认的无参构造方法,除非显示的定义一下
public Person(String name) {
}
public Person() {}
}
class Dog {
//一个类可以定义多个不同的构造方法,构造方法重载
String name;
int age;
//第1个构造器
public Dog(String dName) {
System.out.println("ok~~");
name = dName;
}
//第2个构造器
public Dog(String dName, int dAge) {
name = dName;
age = dAge;
}
}
8.6对象创建的流程分析
看一个案例
class Person{
int age=90;
String name;
Person(String n,int a){
name=n;
age=a;
}}
Person p=new Person(“小倩”,20);
流程分析(面试题)
1)加载 Person 类 (Person.class), 只会加载一次
2)在堆中 开数据空间 , 得到一个地址
3)数据的初始化
(1) 默认初始化 age = 0, name = null
(2) 显示初始化 age = 90 , name = null
(3) 构造器初始化 age= 20 name = “小倩”
(4) 把 堆中的地址,返回给 p
(5) 使用
9this关键字
9.1看一段代码,引出this
9.2什么是this
java虚拟机会给每个对象分配 this,代表当前对象。坦白的讲,要明白this 不是件容易的事,我给大家打一个比方。[上帝创世界小故事]
9.3深入理解this
为了进一步理解this,我们再看一个案例 (ThisTest.java)
public class ThisTest {
public static void main(String[] args) {
Dog dog = new Dog("旺财", 5);
System.out.println("dog的地址(hashcode=)" + dog.hashCode());
dog.showInfo();
Dog dog2 = new Dog("来福", 2);
System.out.println("dog2的地址(hashcode=)" + dog2.hashCode());
dog.showInfo();
//哪个对象调用,this就代表哪个对象
dog.m1();
dog2.m1();
}
}
class Dog{
public String name; // null
public int age; //0
//我们形参,本质就是 局部变量
public Dog(String name, int age){
System.out.println(this.hashCode());
this.name = name;
this.age = age;
}
public void m1() {
System.out.println(this.name);
System.out.println("m1 this.hashCode=" + this.hashCode());
}
public void showInfo(){
System.out.println(name + "\t" + age + "\t");
}
}
对应的this理解的示意图
9.4this的注意事项和使用细节
1)this关键字可以用来访问本类的属性、方法、构造器
2)this用于区分当前类的成员和局部变量
3)访问成员方法的语法:this.方法名(参数列表);
4)访问构造方法(构造器)语法:this(参数列表);
5)this不能在类定义的外部使用,只能在类定义的方法中使用
6)代码
public class ThisDetail {
public static void main(String[] args) {
AA a = new AA();
a.m2();
System.out.println(a.name); // smith
AA a2 = new AA("king");
System.out.println(a2.name); // king
}
}
class AA {
int age = 10;
String name = "tom";
public AA() { //构造器1
//访问构造方法(构造器)语法:this(参数列表)
this("smith"); // this 可以调用其它构造器, 需要在构造器内
}
public AA(String name) {
//this用于区分当前类的成员和局部变量
this.name = name;
}
public void m1() {
//this关键字可以用来访问本类的属性、方法、构造器
System.out.println(this.age);
}
public void hi() {
System.out.println("hi");
}
public void m2() {
System.out.println("m2()");
//访问成员方法的语法:this.方法名(参数列表);
this.hi(); // 可以访问 本类的 hi();
}
}
本文地址:https://blog.csdn.net/huluo1/article/details/110449876
上一篇: javascript本地存储(简介)
下一篇: idea基本设置 - java开发工具