7.1 类与对象 oop
问题:编写一个程序,输入猫名字,显示该猫的名字,年龄,颜色
现有技术:单独定义变量、数组;缺点:不利于数据管理,效率低
类中包含对象(属性 + 行为),如将人类中的属性和行为实例化就是一个具体的人
类与对象的区别与联系
1.类是抽象的,概念的,代表一类事物,如人类,类是数据类型
2.对象是具体的、实际的,代表一个具体的事物,是类的一个个体
对象在内存中存在形式!!!
编辑
属性/成员变量/字段
成员变量 = 属性 = field 字段,可以是基本数据类型,也可以是引用类型(对象、数组)
属性定义语法同变量,默认值同数组
public class Exercise {
public static void main(String[] args]{
//创建对象,p为对象名
Person p = new Person();
//访问属性
p.age;
p.name;
p.sal;
//调用方法
p.speak();
int returnRes = p.getSum(10,20);
System.out.println(returnRes);
}
}
class Person { //创建类 Person
//属性(成员变量、字段)
int age;
String name;
double sal;
//行为(方法)
public void speak(){ //访问修饰符+返回类型(void表示无需返回)+方法名+(形参列表)
System.out.println("我是一个好人");//方法体
}
public int getSum(int num1, int num2) {
int res = num1 + num2;
return res;
}
}
类和对象的内存分配机制
栈:一般存放基本数据类型(局部变量)
堆:存放对象(Cat cat , 数组等)
方法区:常量池(常量,如字符串),类加载信息(只加载一次)
顺序:先加载类信息-->堆中分配空间,有基本数据类型的指向方法区的常量池-->地址赋给对象名(栈),指向对象
7.2 成员方法
基本介绍
在某些情况下,我们需要定义成员方法(简称方法)。比如人类:除了有一些属性(年龄、姓名等),还有一些行为(说话、跑步、学习等),这些行为就需要成员方法来完成。
方法的调用机制原理!!!
编辑
成员方法好处:提高代码的复用性;可以将实现的细节封装起来,然后供其他用户调用即可
定义:
访问修饰符 返回类型 方法名(形参列表){
语句;
return 返回值;//不是必须,如没有返回值时(void)不用
}
注意事项和使用细节
访问修饰符:不写则默认(public、protected、private、默认)
返回数据类型:
1.一个方法最多有一个返回值
2.返回类型可以为任意类型,包含基本类型和引用类型(数组、对象)
3.如果方法要求有返回类型,则方法体中最后的执行语句必须为return值;且返回值类型必须和return的值类型一致或兼容
4.如果方法是void,则方法体中可以没有return语句,或者只写return;
方法名:小驼峰命名、见名知义
行参列表:
1.一个方法可以有0个参数,也可以有多个参数,逗号隔开
2.参数类型可以为任意类型,包含基本类型和引用类型
3.调用带参数的方法时,一定对应着形参列表传入相同类型或兼容类型的参数
4.方法定义时的参数成为形式参数,简称形参;方法调用时的传入参数称为实际参数,简称实参,实参和形参的类型要一致或兼容、个数、顺序必须一致!
方法体:完成功能的具体语句,可以输入、输出、变量、运算、分支、循环、方法调用,但不能在定义方法
方法调用细节
1.同一个类中的方法调用:直接调用即可。方法名();
2.跨类中的方法a类调用b类方法:需要通过对象名调用。及在a类的方法中创建b类,在调用
3.跨类的方法调用与方法的访问修饰符有关
7.3 成员方法传参机制(非常重要)
基本数据类型的传参机制
基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参
public class Exercise {
public static void main(String[] args){
int a = 10;
int b = 20;
T t = new T();
t.swap(a, b);
System.out.println("main方法" + a + b);//a=10; b=20
}
}
class T {
public void swap(int a, int b) {
System.out.println("交换前" + a + b); // a=10;b=20
int temp = a;
a = b;
b = temp;
System.out.println("交换后" + a + b);//a=20;b=10
}
}
引用数据类型的传参机制
引用类型传递的是地址(传递也是值,但是是值的地址),可以通过形参影响实参
/*
案例:
B类中编写方法test100,接收数组,在方法中修改数组,原数组变化吗? 会
B类中编写方法test200,接收Person(age,sal)对象,在方法中修改该对象属性,原对象是否变化, 会
*/
public class Exercise {
public static void main(String[] args){
B b = new B();
int[] arr = {1, 2, 3};
b.test100(arr);
System.out.println("main的arr数组");
for(int i = 0, i < arr.length; i++){
System.out.println(arr[i] + " ");
}
System.out.println();
Person p = new Person();
p.name = "jack";
p.age = 10;
b.test200(p);
//如果执行 p = null; 下面结果为 10
//如果执行 p = new Person();下面结果为 10
System.out.println("main的p.age =" + p.age); //10000
}
}
class Person {
String name;
int age;
}
class B {
public void test100(int[] arr){
arr[0] = 200;//修改数组
System.out.println("test100的arr数组");
for(int i = 0, i < arr.length; i++){
System.out.println(arr[i] + " ");
}
System.out.println();
}
public void test200(Person p){
//p.age = 10000;//修改对象属性
p = new Person();
p.name = "tom";
p.age = 99;
//思考
//p = null;
}
}
编辑
成员方法返回类型是引用类型(数组、对象)实例
public class Exercise {
public static void main(String[] args){
Person p = new Person();
p.name = "milan";
p.age = 100;
MyTools tools = new MyTools;
Person p2 = tools.copyPerson(p);
//到此p和p2是Person对象,但是是两个独立的对象,属性相同
}
}
class Person {
String name;
int age;
}
class MyTools {
public Person copyPerson(Person p) {
Person p2 = new Person();
p2.name = p.name;
p2.age = p.age;
return p2;
}
}
7.4 方法递归调用(非常非常重要) factorial
递归就是方法自己调用自己,每次调用时传入不同的变量
阶乘问题
public class Exercise {
public static void main(String[] args) {
T t1 = new T();
int res = t1.factorial(5);
System.out.println("5的阶乘为" + res);
}
}
class T {
public int factorial(int n) {
if(n == 1) {
return 1;
}else {
return factorial(n - 1) * n;
}
}
}
编辑
递归重要规则
1.执行一个方法时,就创建一个新的受保护的独立栈空间
2.方法的局部变量时独立的,不会互相影响,比如n
3.如果方法中使用的是引用类型(数组、对象),就会共享该引用类型的数据
4.递归必须向退出递归的条件逼近,否则就是无限递归
5.当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕
递归调用实例--迷宫问题
public class MiGong {
public static void main(String[] args){
//创建迷宫,1表示障碍物,0表示可以走
int[][] map = new int[8][7];
for(int i = 0; i < 7; i++) {
int[0][i] = 1;
int[7][i] = 1;
}
for(int i = 0; i < 8; i++) {
int[i][0] = 1;
int[i][6] = 1;
}
map[3][1] = 1;
map[3][2] = 1;
//遍历数组,形成迷宫
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map[i].length; j++) {
System.out.println(map[i][j] + " ");
}
System.out.println();
}
//找路
T t1 = new T();
t1.findWay(map, 1, 1);
//重新遍历数组,找到出路
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map[i].length; j++) {
System.out.println(map[i][j] + " ");
}
System.out.println();
}
}
}
class T {
//创建找路方法findWay;规定2表示可以走,3表示走过;起始位置(1,1),目标位置(6,5)
//找路策略为下-右-上-左;当目标位置mao[6][5] = 2;则找到通路
public boolean findWay(int[][] map, int i, int j) {
if(map[6][5] == 2) {
return true;
}else {
if(map[i][j] == 0) {
map[i][j] = 2;
if(findWay(map, i + 1, j){
return true;
}else if(findWay(map, i, j + 1){
return true;
}else if(findWay(map, i - 1, j){
return true;
}else if(findWay(map, i, j - 1){
return true;
}else {
map[i][j] = 3;
return false;
}
}else {
return false;
}
}
}
7.5 方法重载 overload
java中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!方法重载减轻了起名和记名的麻烦。
注意事项和使用细节
1.方法名必须相同;2.行参列表必须不同(参数名无要求);3.返回类型 无要求
7.6 可变参数
java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。通过可变参数实现。
访问修饰符 返回类型 方法名(数据类型... 形参名){
}
public class Exercise {
public static void main(String[] args){
HspMethod m = new HspMethod();
System.out.println(1,5,100);
System.out.println(1,5,100,333,55,67);
}
}
class HspMethod {
public int sum(int... nums){
int res = 0;
for(int i = 0; i < nums.length; i++) {
res += nums[i];
}
return res;
}
}
注意事项和使用细节
1.可变参数的实参可以为0个或任意多个
2.可变参数的实参可以为数组
3.可变参数的本质就是数组
4.可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
5.一个形参列表只能出现一个可变参数
7.7 作用域 varscope
基本使用
1.在java编程中,主要的变量就是属性(成员变量)和局部变量
2.我们说的局部变量一般是指在成员方法中定义的变量
3.java中作用域的分类:1)全局变量:也就是属性,作用域为整个类体;2)局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中
4.全局变量(属性)可以不赋值,直接使用,因为有默认值。局部变量必须赋值后,才能使用,因为没有默认值。
注意事项和细节
1.属性和局部变量可以重名,访问时遵循就近原则
2.在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名
3.属性生命周期长,伴随着对象的创建而创建,销毁而销毁。局部变量声明周期短,伴随着它的代码块的执行而创建,结束而销毁,即在一次方法调用过程中。
4.作用域范围不同:全局变量可以被本类或其他类使用(通过对象调用,第一种是在类的方法中新建类实现跨类访问;第二种是在类的方法中传入对象调用);局部变量只能在本类中对应的方法中使用
5.修饰符不同:全局变量可以加修饰符;局部变量不行
7.8 构造方法/构造器 constructor
需求:前面创建对象时,是先创建在赋值。若要求创建时就赋值,利用构造器
【修饰符】 方法名(形参列表){
方法体;
}
定义:构造方法又叫构造器,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。
说明:1.构造器的修饰符可以默认,也可以是其余3种
2.构造器没有返回值,也不能写void
3.方法名 和 类名字必须一样
4.参数列表 和 成员方法规则一样
5.构造器调用由系统完成
class Person {
String name;
Int age;
public Person(String pName, int pAge){ //构造器
name = pName;
age = pAge;
}
}
注意事项和使用细节
1.构造器重载:一个类可以定义多个不同的构造器
2.构造器是完成对象的初始化,并不是创建对象
3.在创建对象时,系统会自动调用该类的构造方法
4.如果没有定义构造器,系统会自动给类生成一个默认的无参构造器(默认构造器)
5.一旦定义了自己的构造器,默认的构造器就覆盖了,也就不能使用默认的无参构造器,除非显示的定义一下
//如Dog类中,显示定义
Dog(){
}
7.9 对象创建的流程分析
参考以前的流程分析图
7.10 this 关键字
问题:改进构造器参数名,将pName、pAge改为name、age更好,但根据作用域原则,name的值就是null,解决方法--> this
哪个对象调用,this就代表哪个对象
注意事项和使用细节
1.this关键字可以用来访问本类的属性、方法、构造器
2.this用于区分当前类的属性和局部变量
3.访问成员方法的语法:this.方法名(参数列表);
4.访问构造器语法:this(参数列表);注意只能在构造器中使用,即只能在构造器中访问另外一个构造器,必须放在第一条语句
5.this不能在类定义的外部使用,只能在类定义的方法中使用
标签:map,int,方法,基础,Person,面向对象编程,println,部分,public From: https://www.cnblogs.com/aduantongxue/p/16602239.html