类与对象(面向对象基础)
java内存结构分析
- 栈:一般存放基本数据类型(局部变量)
- 堆:存放对象(数组等)
- 方法区:常量池(常量,比如字符串),类加载信息
- 示意图
java创建对象流程
- 先加载Person类信息(**属性 ** 和 方法信息,只会加载一次)
- 在堆中分配空间,进行默认初始化
- 把地址赋给P,P就指向对象
- 进行指定初始化,比如p.name=“jack”
方法调用机制
对象=属性+方法
class 类名{
属性;(int a;)
方法;( public void (形参) { 方法体 } )
}
属性
叫法: 属性=成员变量=filed (有点像c语言的结构体)
public class j {
public static void main(String[] args) {
Person p1=new Person();
p1.age=20;
Person p2=p1;//地址传递,引用赋值,看上面图
}
}
class Person{
int age ;//属性定义类型可为任意类型
String name;
}
方法
感觉很像c语言的自定义函数
- 方法可以用来接受类
方法体里面不可再次定义方法
public class j {
public static void main(String[] args) {
int a=10,b=9;
Person p=new Person();
int sum=p.sum(a,b);
System.out.println(sum);
}}
class Person{
int age ;
String name;
//public 表示方法公开,int 表示返回类型
// sum:方法名,()形参列表,{方法体}
public int sum(int a,int b){
int c=a+b;
return c;
}}
-
同一类中的方法直接调用即可
class a{ public void spack(){ System.out.println("you are a bad girl"); } public void ok(){ spack(); //直接调用speak }}}
- A类调用B类方法:需要通过对象名调用(需要new一下),跨类的方法调用和方法的访问修饰符相关
class A{ int a1=1; public void a2(){ System.out.println("测试"); } } class B{ public void b(){//只可在方法中调用 A c=new A(); c.a2(); } //A c=new A();错误,不可在类中调用 }
- 主函数把基本数据类型传入到类方法中进行操作,不会影响主函数中的值
- 主函数把引用类型(数组)传入类方法进行操作,会改变数组的值,因为传的是地址
- 对象可操作对象,可修改对象的属性
public class a {
public static void main(String[] args) {
AA p=new AA();
BB c=new BB();
p.panduan(c);
System.out.println(c.n);//输出10;
}}
class BB{
int n=0;
}
class AA{
public void panduan(BB p) {
p.n=10;
}}
克隆对象
用方法new一个对象然后返回
//p和p2为独立对象
public class a {
public static void main(String[] args) {
person p=new person();
tool copy =new tool();
person p2=new person();
p2=copy.copy(p);
}}
class person{
String name;
int age;
}
class tool{
public person copy (person p){
person p2=new person();
p2.age=p.age;
p2.name=p.name;
return p2;
}
}
//若直接p2=p;则为同一对象,多了个名而已;
方法递归调用
方法的重载
介绍:java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致!
方法名:必须相同 **形参列表:必须不同 ** 返回类型:无要求
public class a {
public static void main(String[] args) {
Calculator p=new Calculator();
int sum1=p.calculate(1,1);
double sum2=p.calculate(1,1.1);
}}
class Calculator {
public int calculate(int a,int b){
return a+b;
}
public double calculate(int a,double b){
return a+b;
}
}
可变参数的使用
将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法
public class a{
public static void main(String[]args){
Method p=new Method();
int sum=p.sum(1,2,3,4,5);
System.out.println(sum);
}}
class Method{
//int...表示接受可变参数,类型为int
//使用可变参数时,可以把他当做数组来使用
public int sum(int...nums){
System.out.println("参数个数"+nums.length);
int res=0;
for(int i=0;i<nums.length;i++){
res+=nums[i];
}
return res;
}
}
- 可变参数的本质为数组
- 可变参数的实参可以为数组
- 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
public void f2(String str,double...nums){};
- 一个形参列表中只能出现一个可变参数
变量作用域
全局变量:也就是属性 1.作用域为整个类; 2.可以通过对象调用; 3.可以加修饰符;
局部变量:属性之外的其他变量,1.作用域为定义它的代码块中;2.只能在本类中对应的方法中使用;3.不可以加修饰符;
-
全局变量可以不赋值,因为有默认值。
-
局部变量必须赋值后才能使用,没有默认值
-
属性和局部变量可以重名
构造器(构造方法)
类的一种特殊的方法,主要作用是完成对新对象的初始化。
特点:1.方法名和类名相同
2.没有返回值
3.创建对象时,系统自动的调用该类的构造器完成对象的初始化
public class a{
public static void main(String[]args) {
person p=new person("北冥有鱼",20);
}}
class person{
String name;
int age;
public person(String pname,int page){//和类同名,无返回值
name=pname;
age=page;
}
}
如果没有定义构造器,系统会自动给类生成一个,默认无参构造器(默认构造器)
一旦定义了自己的构造器,默认构造器就被覆盖了
构造器重载
public class a{
public static void main(String[]args) {
person p=new person(20);//自动调用2
}}
class person{
String name;
int age;
public person(String pname,int page){//1
name=pname;
age=page;
}
public person(int page){//2
age=page;
}
}
this
哪个对象调用,this就代表哪个对象
-
this可以用来访问本类的方法、属性、构造器
-
this只能在类定义的方法中使用
-
用于区分当前类的属性和局部变量
-
不能在类定义的外部使用
public class a{
public static void main(String[] args) {
dog dog1=new dog("大黄",10);
}
}
class dog{//this指向dog1;
int age;//this.age为这个
String name;
public dog(String name,int age){
this.age=age;
this.name=name;
}
public out(){
System.out.println(name+this.name);
//name是根据就近原则去寻找
//this.name 明确指明是对象的name;
}
}
==============================================
class t{//this 构造器访问构造器
public t(){
this(10);//必须放在第一条语句
}
public t(int a){
System.out.println("a");
}
}