方法
- 方法是解决一类问题,例如专门解决加法运算,交换的一类有序结合
- 方法包含类或对象
- 方法在程序中被创建,在其他地方被引用
方法就是一个代码块,设计方法时最好保证一个方法一个功能
方法的定义
- 方法包含一个方法头和一个方法体
- 修饰符:定义了该方法的询问类型:public,private,static等
- 返回类型:返回类型如:float,void等
- 方法名
- 参数类型:像一个占位符,当方法被调用时
public class Demo01 {
public static void main(String[] args) {
//add(1,1) alt+回车自动补齐
int add = add(1, 1);
System.out.println(add);
hello();
}
public static int add(int a,int b){
return a + b ;
}
public static void hello(){
System.out.println("你好");
}
}
基本方法:
修饰符 返回值类型(void 不返回) 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
面向对象和面向过程的区别:
- 面向对象:是分析解决问题的步骤,然后用函数把这些步骤一一实现,然后在使用的时候一一调用。性能较高。注重过程!!
- 面向对象:把构成问题的事情分解成各个对象,建立对象的目的是为了描述某个事物在解决整个问题的过程中发生的行为
面向对象:封装,多态,继承,可维护性,易扩展性等
面向对象
类:某一类事物整体描述/定义(属性+ 方法)
对象:万事万物就是对象,每个对象都是类下面的产物
三大特性:封装,多态,继承
public class Person {
String name;
int age;
double height;
double weight;
char sex;
public void eat() {
System.out.println("吃饭");
}
public void drink(String adress) {
System.out.println("我在" + adress + "喝可乐");
}
public void play(){
System.out.println("玩手机");
}
}
public class Persontest {
public static void main(String[] args) {
Person person = new Person();
person.name = "prestige";
person.age = 23;
person.height = 170;
person.weight = 70;
person.sex = '女';
person.drink("酒店");
person.play();
}
}
new之后,调用的是person的模板
练习
创建Person类的对象,设置该对象的name,age和sex属性,调用showage()方法显示age值,调用addage()方法 给对象age的值增加两岁
public class Persontest {
public static void main(String[] args) {
Person person = new Person();
person.name = "prestige";
person.age = 23;
person.sex = '女';
person.showage(23);
person.addage(23);
}
}
public class Person {
String name;
int age;
double height;
double weight;
char sex;
public void showage(int age) {
System.out.println(age);
}
public void addage(int age) {
System.out.println(age + 2);
}
}
构造器
特性:
- 一个类即使什么都不写,它也会存在一个方法(本身就有一个方法)
- 构造方法
- 和类名相同
- 没有返回值
- 作用:
- 使用 new 关键字,本质是在调用构造器
- 在无参构造器中,无参构造器可以实例化初始值
public class Person {
//属性
String name;
String age;
//方法--->无参构造器,可以理解为初始化
public Person() {
System.out.println("我是一个学生");
}
}
有参构造器:一旦定义了有参构造器,无参构造器就必须显示定义,因为默认的无参构造器失效了
public class Person {
//属性
String name;
String age;
//方法--->无参构造器
public Person() {
System.out.println("我是一个学生");
}
//有有参构造器,必须显式定义无参构造器
public Person(String name, String age) {
this.name = name;
this.age = age;
}
public class PersonTest {
public static void main(String[] args) {
Person person = new Person();
Person person01 = new Person("herb", "18");
System.out.println(person01.name);
System.out.println(person01.age);
}
}
this
修饰属性
- 如果想要访问的是属性的话,前面就加上this。 this.age 代表 外部属性的 age
- 当不发生重名问题,this可以省略不写
- 当发生重名问题,this 不可以省略。
当发生重名的时候,就近原则
public class Student {
//属性
String name;
int age;
double height;
//无参构造器
public Student() {
}
//有参构造器
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
//方法
public void eat(String name) {
System.out.println(name);
System.out.println(this.name);
}
public static void main(String[] args) {
//创建对象
Student student = new Student("herb", 18, 120);
student.eat("aaa");
}
}
this修饰方法
在同一个类中,方法之间可以互相调用,this 可以省略不写
//方法
public void eat() {
System.out.println(name);
System.out.println(this.name);
}
public void play() {
this.eat();
System.out.println("===================");
eat();
System.out.println("看电影");
}
this修饰构造器
同一个类中,构造器之间可以互相调用。
this(传入实参)
this修饰构造器,必须放在代码的第一行:this(),this(12)…
//无参构造器
public Student() {
System.out.println("1111");
}
//有参构造器
public Student(String name, int age, double height) {
//this();
this(name);
this.name = name;
this.age = age;
this.height = height;
}
public Student(String name) {
this.name = name;
System.out.println("进来了");
}
方法重载
在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同
“两同一不同”
同一个类、相同的方法名
参数列表不同:参数个数不同、参数类型不同
public class OverLoadTest {
public static void main(String[] args) {
OverLoadTest overLoadTest = new OverLoadTest();
overLoadTest.getSum(1, 2);
overLoadTest.getSum(1.0, 1.1);
overLoadTest.getSum(1, "s");
overLoadTest.getSum("s", 1);
}
//方法的重载
public void getSum(int i, int j) {
System.out.println("1");
}
public void getSum(double d1, double d2) {
System.out.println("2");
}
public void getSum(String s, int i) {
System.out.println("3");
}
public void getSum(int i, String s) {
System.out.println("4");
}
可变个数的形参
- 可变形参的格式:数据类型… 变量名
- 可变形参声明必须在末尾
- 可变形参在方法中的形参中,最多只能声明一个可变形参
public class Args {
public void test(String... str) {
System.out.println("show(String... str)");
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
}
public void test(int i, String... str) {
System.out.println("ssss");
}
public static void main(String[] args) {
Args test = new Args();
test.test(new String[] {"AA", "eagle", "CC"});
}
封装
-
将数据隐藏,提供相应的方法进行获取
- 高内聚,低耦合
-
封装(数据隐藏)
- 通常,应该禁止直接访问一个对象中数据的实际表示,而应该通过操作接口来访问
-
属性私有get/set private
public class Girl {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class GirlTest {
public static void main(String[] args) {
Girl girl = new Girl();
girl.setAge(32);
int age = girl.getAge();
System.out.println(age);
}
}
作用:
- 提高程序安全性
- 隐藏代码实现细节
- 统一接口
- 增强系统可维护性
四种权限修饰符的理解
public,protected,default,private
修饰符 | 类内部 | 同一个包 | 不同包 | 同一个工程 |
---|---|---|---|---|
private | YES | NO | N | NO |
default | YES | YES | N | NO |
protected | YES | YES | YES | NO |
public | YES | YES | YES | YES |
内存分析
栈内存(存放基本数据类型)
后进先出
当线程进入一个java方法函数时,就是会在当前线程的栈里压入一个栈桢,用来保存当前线程的状态(参数,局部变量,中间计算过程和其他的数据)当退出函数方法时,修改栈指针就可以把栈中内容销毁
堆内存
唯一的目的就是存放对象实例。
初始化对象,成员变量(非static变量),字符串常量池,所有对象实例和数组都在堆上分配
方法区
方法区包含的都是整个程序中永远唯一的元素,如class,static变量的静态属性
总的来说,堆内存保存的是对象的真实信息,只要new出来的对象都在队中;栈中保存的一块堆内存的地址,通过地址可以找到对象的真实对象数据;方法区是保存静态属性
栈中的p是参数,指向堆中的对象
动态改变
执行结束后,栈中的内容会被销毁
形参和实参
- 形式参数:在定义函数函数名和函数体的时候使用的参数,目的是用来接受调用该函数时传入的参数。
- 实际参数:在调用有参函数时,主调函数和被调函数之间有数据传输
public class Demo01 {
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
demo01.sout("hello"); //实际参数
}
public void sout(String name) { //形式参数
System.out.println(name);
}
}
值传递和引用传递
- 值传递:是指在调用函数时,将原始对象复制一份作为实参给形参,当在函数中对参数进行修改时,不会影响实际参数,
- 引用传递:是指在调用函数时,将原始对象直接作为实参传递给形参,一旦函数在函数对其进行修改,将会影响实参
java的方法是值传递
public class AA {
public static void main(String[] args) {
AA aa = new AA();
int i = 100;
aa.change(i);
System.out.println(i);
}
public void change(int i) {
i = 20;
System.out.println(i);
System.out.println("进来了");
}
}
可见,change()方法内部对 i 的值进行修改 并没有改变实际参数 i 的值
public class Person {
int id;
int age;
String school;
public Person(int a, int b, String c) {
this.id = a;
this.age = b;
this.school = c;
}
public void setAge(int a) {
this.age = a;
}
}
public class PersonTest {
public static void main(String[] args) {
PersonTest p = new PersonTest();
int age = 40;
Person tom = new Person(1, 20, "herb");
Person jack = new Person(2, 30, "leilei");
p.change1(age);
p.change2(tom);
p.change3(jack);
System.out.println(age);
System.out.println("tom");
System.out.println("id:" + tom.id + ",age:" + tom.age + ",school:" + tom.school);
System.out.println("jack");
System.out.println("id:" + jack.id + ",age:" + jack.age + ",school:" + jack.school);
}
public void change1(int i) {
i = 100;
}
public void change2(Person p) {
p = new Person(3, 25, "eagle");
}
public void change3(Person p) {
p.setAge(25);
}
}
方法结束,栈桢消失
Person tom = new Person(1, 20, "herb");
Person jack = new Person(2, 30, "leilei");
p.change1(age);
public void change1(int i) {
i = 100;
}
p.change2(tom);
public void change2(Person p) {
p = new Person(3, 25, "eagle");
}
p.change3(jack);
public void change3(Person p) {
p.setAge(25);
}