面向对象基础篇
前面的运算符和选择循环结构听起课来还并没有很吃力,到了面向对象这部分总是听的一知半解,过一段时间就又忘掉了,所以准备做一下笔记加深印象。
类与对象
类:抽象的,对某一类事物的描述。
对象:具体的,某一类事物实际存在的每个个体。
类与对象的创建
右键src目录,新建Java类
命名时,一般使用英文单词,首字母大写,不能出现任何特殊字符
添加属性作为成员变量
public class Person {
String name; //=null,有初始值,为空
int age;
String sex;
}
创建实例对象
public class Main {
public static void main(String[] args) {
new Person(); //用new关键字来创建某个类的对象,注意new后面需要跟上类名()
}
对象的使用
使用一个变量来指代某个对象,只不过引用类型的变量,存储的是对象的引用,而不是对象本身:
public static void main(String[] args) {
//这里的p1存放的是对象的引用,而不是本体,通过对象的引用来间接操作对象
Person p1=new Person();
}
有了对象的引用之后,就可以进行操作了:
public static void main(String[] args) {
Person p1=new Person();
p1.name="小鹏";
p1.age=21;
p1.sex="男";
System.out.println(p1.name);
}
不同对象的属性是分开独立存放的,修改一个对象的属性并不会影响到其他对象
关于对象类型的变量,我们也可以不对任何对象进行引用:
public static void main(String[] args) {
Person p=null;//此时变量没有引用任何对象
p.name="小红";
System.out.println(p.name);
}
此时程序在运行的过程中,出现了异常。
这里出现的是空指针异常,是因为我们去操作一个值为null的变量导致的。
方法的创建与使用
方法的定义如下:
返回值类型 方法名称(){
方法体
}
若没有返回值,只是完成任务,那么可以用void表示没有返回值:
void hello(){ //void表示方法没有返回值
System.out.println("我叫"+name);
}
//
p1.hello(); //我们只需要使用.运算符,就可以执行定义好的方法 .方法名称()即可
函数的返回值是int类型,只需要使用return关键字来返回一个int类型的结果就可以了:
int sum(int a,int b){
return a+b ;
//return之后编写代码,会导致编译不通过,因为存在不可达语句
//如果程序中出现分支语句,每一个分支必须有返回值
}
//
int result = p1.sum(18,10);
System.out.println(result);
如果方法没有返回值,我们也可以使用return语句,不需要跟上任何内容,以提前结束语句:
void test(int c){
if(c==10) return;
System.out.print("hello");
}
参数的传递问题:
参数的传递,会在调用方法的时候,对参数的值进行复制,方法中的参数变量,不是我们传入的变量本身:
void swap(int a,int b){ //这个函数是为了交换a和b的值
int tmp=a;
a=b;
b=a;
}
public static void main(String[] args) {
Person p=new Person();
int a=5,b=9;
p.swap(a,b);
System.out.println("a="+a+",b="+b);
}
//运行的结果
a=5,b=9
a,b的值并没有发生交换,实际上这里仅仅是将值复制给了函数里面的变量
方法的进阶使用
如果要在方法中访问到当前对象的属性,那么可以使用this关键字,来明确表示当前类的实例对象本身:
void setName(String name){
this.name=name;
}
如果方法内没有出现重名的情况,那么默认情况下可以不使用this关键字来明确表示当前对象:
String getName(){
return name;
}
方法的重载
一个类中可以包含多个同名的方法,但是需要的形式参数不一样,方法的返回类型,可以相同,也可以不同,但仅仅是返回类型不同不行!
int sum(int a,int b){
return a+b ;
}
double sum(double a,double b){
return a+b;
}
方法间可以相互调用,但会出现栈溢出错误
也可以自己调用自己,称为递归调用,直接编写也会栈溢出错误,但是如果我们给其合理的设置出口:
int test(int n){
if(n==0) return 0;
return test(n-1)+n; //返回的结果是下一层返回的结果+当前这一层的n
}
//
计算从1加到n的和
构造方法
每一类都有一个默认的构造方法:
public Person(){
}
构造方法会在new的时候自动执行
public class Person {
String name;
int age;
String sex;
Person(){ //构造方法不需要指定返回值,并且方法名称与类名相同
name="小二"; //构造方法会在对象创建时执行,我们可以将各种需要初始化的操作都在这里执行
age=22;
sex="女";
System.out.println("我构造成功了");
}
}
我们也可以为构造方法设定参数:
public class Person {
String name;
int age;
String sex;
Person(String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
}
我们自己定义一个构造方法后,会覆盖掉默认的那一个无参构造方法,除非我们手动重载一个无参构造,否则要创建这个类的对象,必须调用我们自己定义的构造方法。
成员变量的初始化在构造方法之前就已经完成了。
我们也可以在类中添加代码块,代码块同样会在对象构造之前进行,在成员变量初始化之后执行:
public class Person {
String name;
int age;
String sex;
{
System.out.println("我是代码块");
}
Person(String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
}
成员变量的初始化>- 代码块>- 对象构造
静态变量与静态方法
静态变量
一般情况下,我们并不会通过一个具体的对象去修改和使用静态属性,而是通过这个类去使用
若一个对象改变了静态变量的值,其他的对象读取的也是被改变的值
public class Person {
String name;
int age;
String sex;
static String info; //静态变量
}
//
public static void main(String[] args) {
Person.info="让我看看";
System.out.println(Person.info);
}
静态方法
static void test(){ //静态方法
System.out.println("aaaa"); //静态方法中,无法获取成员变量的值,只能调用静态变量
}
静态代码块
static { //静态代码块可以用于初始化静态变量
info ="测试";
}
静态变量在什么时候进行初始化呢?
- 访问类的静态变量,或者为静态变量赋值
- new创建类的实例(隐氏加载)
- 调用类的静态方法
- 子类初始化时
- 其他情况 反射...