类和对象
1 类是用来定义对象的模板。当使用一个类创建了一个对象时,也相当于给出了这个类的一个实例。因此,类是一个抽象的概念,对象则是类的一个具体实例。
2 C是面向过程的,重在解决问题的过程;Java是面向对象的,重在描述某个事物在整个问题的步骤中的行为。
面向对象三大特点
封装性、继承性、多态性。
成员变量、成员方法与局部变量
class Person
{
//成员变量(表示类的静态属性)
String name;
int age;
/*char sex;
float weight;
boolean heath; */
//成员方法(从动态方式来表示类)
void say() //方法习惯小写
{ //int age;错误,必须要初始化
System.out.println("name:"+name+";"+age); //name:LL;3
} //name:null;0
} //name:LL;3
class Test-4.1
{ public static void main(String[] args)
{ Person P1=new Person();
Person P2=new Person(); //对象之间没有联系
P1.age=3;
P1.name="LL";
//P1=null;对象的生命周期结束, 空指针异常
P1.say();
P2.say();
P2=P1; //引用的传递
P1=null;
P2.say();
}
}
1 局部变量一定要初始化,成员变量有默认值,可以不初始化
局部变量:方法内的变量; 成员变量:类里的变量
2 say方法可以直接访问同一个类中的age变量 ,如果一个方法中有与成员变量同名的局部变量,该方法中对这个变量名的访问是局部变量,而不再是成员变量。
3 main方法所在类为启动类,可在多个类中编写main方法,但运行时仅能运行一个main方法。
成员变量类型 | 初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0D |
char | ‘\u0000’(表示为空) |
Boolean | false |
all reference type | null |
对象的比较
class Person
{ String name=“LL";
int age=-3;}
class Test-4.2
{
public static void main(String[] args)
{ Person p1=new Person();
Person p2=new Person();
if (p1==p2)
/* 等价于if(p1.equals(p2))*/
System.out.println("YES");
else
System.out.println("NO");} //NO
}
1 如果是基本类型比较,那么只能用两个等于号来比较,不能用equals,否则编译不能通过;只要两个简单类型值相等即返回ture,否则返回false。
2 重写了equals()方法的有些类,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double、String等的引用变量(包装类),双等于号是比较地址的,而equals比较内容。
3 自定义的类 没有重写Object中的equals方法,则继承该方法,比较的是内存地址。
4 如果测试两个简单类型的数值是否相等,则一定要用双等于号来比较;如果要比较两个引用变量对象的值是否相等,则要用对象的equals()方法进行比较;如果需要比较两个引用变量是否指向同一对象,则使用“==”来进行比较。
5 对于String(字符串) 、StringBuffer(线程安全的可变字符序列)、StringBuilder(可变字符序列)这三个类。举String作进一步的说明。
class Test-4.3
{
public static void main(String[] args)
{ String s1 = "123";
String s2 = "123";
String s4 = new String("123");
String s5 = new String("123");
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
System.out.println(s4 == s5); //false
System.out.println(s4.equals(s5)); //true
System.out.println(s1 == s4); //false
System.out.println(s1.equals(s4)); //true
}
}
匿名对象
1 不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象, 如:new Person().shout(); 匿名对象,一产生即为垃圾,等待gc回收。
2 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
3 经常将匿名对象作为实参传递给一个函数调用。
class Person
{
String name="LJS";
int age=-3;
}
class Test-4.5
{ public static void main(String[] args)
{ Person P1=new Person();
//new Person();
fun(P1); //Person@c17164
fun(new Person()); //Person@1fb8ee3
}
static void fun (Person p)
{System.out.println(p);}
}
class Test-4.6
{
public static void main(String[] args)
{
String s1 = "LL";
if ("LL".equals(s1))
/*LL是匿名对象,(s1.equals("LL")是错误的方式*/
{
System.out.println("cg"); //cg
}
}
}
封装性(private)
1 其核心思想是将数据和对数据的操作封装在一起。封装是指隐藏对象的属性和实现细节,仅仅对外公开接口。4种访问控制级别:
public:对外公开,访问级别最高;
protected:只对同一个包中的类或者子类公开;
默认:只对同一个包中的类公开;
private:不对外公开,只能在对象内部访问。
2 private优点:
(1)隐藏类的实现细节;
(2)让使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
(3)便于修改,增强代码的可维护性
3 设置公用通道,实现从别的类进行访问:通过getXxx()(Xxx表示要访问的成员变量的名字),来读取成员变量操作,另外setXxx()用来对这个成员变量赋值。
class Person
{ private int age=10;//私有的成员变量
//setXxx
public void setAge(int x)
{ if(x<-1)
return;
age=x;} //可加控制输出条件
public int getAge() {return age;}
void say() {System.out.println("age:"+age);}
}
class Test-4.7
{ public static void main(String[] args)
{ Person p=new Preson();
//p.age=-10; 编译不通过
p.setAge(-10);
p.say();} //age:10
}
构造方法
1 构造方法的特征:
(1)名称和类名称一样;
(2)没有方法的返回类型;
(3)不能在方法中用return语句返回一个值(void都没有)。
2 构造方法被系统(JVM)自动调用,只要有生成对象,就必须调用相应的构造方法。
3 构造方法负责对象的初始化工作,为实例变量赋予合适的初始值。当用new创建内存时必须运行构造方法。
class Person
{
String name; // 平时一定要封装
//public Person() {} 系统默认的,没有参数的构造方法
public Person() {System.out.println("i am here");} //i am here
public void say() {System.out.println(name);} //null
public String getInfo() {name=“LL”; return name;} //LL
}
class Test-4.8
{ public static void main(String[] args)
{ Person p=new Person(); //每次创建对象,都会
自动调用一次构造方法,打印"I am here"
p.say();
System.out.println(p.getInfo());}
}
方法重载
1 java中每一个类都有默认的构造方法,它是无参的。但一旦写了一个有参数的构造方法,默认的构造方法就没有了。
2 重载构造方法可以完成不同初始化的操作, 如:Person p3=new Person(“LL”,3);语句,创建指定类的新实例对象,在堆内存中为实例对象分配内存空间,并调用指定类的构造方法,最后将实例对象的首地址赋值给引用变量p3。
3 方法的重载:多态的表现。同一种功能,有多种实现方式,采用哪种调用方式,取决于调用者给定的参数。
4 方法重载:
(1)方法名一样,参数列表(个数,类型)不一样。
(2)返回类型不一样,参数列表一样,不构成重载。
5 方法重载(静态多态),方法覆盖(动态多态)。
class Person
{ String name; int age;
public Person(){}
public Person(String n) {name=n;}
public Person(int x) {age =x;}
public Person(String n,int x) {name =n; age =x;}
public void say()
{ System.out.println(name+" ;"+age);}
}
class Test-4.9
{ public static void main(String[] args)
{ Person p=new Person("LJS"); //画内存图
Person p1=new Person("LJS",3);
p.say(); //LJS ;0
p1.say();} //LJS ;3
}
this关键字
1 用法
(1)修饰属性(成员变量)this.成员变量名;
(2)修饰成员方法 this.方法名;
(3)调用构造方法 this()
对this的调用必须是构造器中的第一个语句;当彼此都调用this时,必须有一个没有this的构造方法
(4)表示当前对象(当前调用方法的对象) this。
2 this()操作必须放在第一行,构造方法的调用必须在对象生成之前。没有调用相应方法,无法生成对象。
3 this表示当前对象(当前调用方法的对象)
谁调用此方法,谁就是当前对象
隐含对象this,指向自己本身
class Person
{ String name;
int age;
public Person()
{ /*this("LJS",3);
错误,递归构造器调用,递归方法的无限调用,
必须留一个出口*/
System.out.println("i am here"); }
public Person(String name)
{ this();
this.name=name; }
public Person(int age)
{ this();
this.age=age; }
public Person(String name,int age)
{ this(name);
this.age=age; }
void say()
{ System.out.println(this.getInfo()); }
String getInfo()
{return name;}
}
class Test-4.10
{
public static void main(String[] args)
{ new Person();
Person p=new Person("LL",3); //i am here
p.say();} //i am here
} //LL
class Person
{ public void print()
{ System.out.println(this); }
}
class Test-4.11
{
public static void main(String[] args)
{
Person p=new Person();
Person p1=new Person();
System.out.println(p);
p.print(); /直接打印对象,地址或引用
System.out.println(p1); //Person@c17164
p1.print(); //Person@c17164
} //Person@1fb8ee3
} //Person@1fb8ee3
class Money
{ int i=5;
public Money() { }
public Money(int i) //构造方法, i为局部变量
{ this.i=i; } //第一个i为局部变量,第二个i为成员变量
public Money add() //成员方法,返回值是对象
{ i++; //i为成员变量
return this;}
void print()
{System.out.println(i);} //13
}
class Test-4.12
{ public static void main(String[] args)
{ Money m1=new Money(10);
m1.add().add().add().print();}
}