定义
具体 —> 抽象
对象1,对象2 —> 类
多个对象,可以抽象出 类
类 可以产生多个对象
类和对象的组成部分
桌子:类
这个桌子:对象
类可以细分,但细分并不一定是对象。
人 —> 顾客 —> VIP会员 都是抽象范围,都是类
int num = 10;
String str = “zs” ;
类 对象 = 类() ;
Person zs = new Person();
属性:就是全局变量
全局变量:
方法以外,类以内,有初始值(数据类型的默认值 int 0)
String name;
局部变量:
方法以内,无初始值,使用前必须赋初值
可以和全局变量重名,并且优先级高,会覆盖全局
String name = “abc”;
类的定义
格式
class 类名称{ ** **//注意这里没有static因为此时定义的方法将要由对象调用,不像之前直接由主方法调用
数据类型 属性;
…
public 返回值的数据类型 方法名称 (参数1,参数2…){
程序语句;
return 表达式;
}
}
定义person类
class Person{
String name; //声明姓名属性
int age; //声明年龄属性
public void tell(){ //获取信息方法
System.out.println("name:"+name+",age"+age);
}
}
在以上程序中,Person类定义了name和age两个属性,之后又定义了tell方法,此方法的功能就是打印这两个属性的内容。
对象的创建和使用
格式
类名 对象名称 = null;//声明对象
对象名称 = new 类名 () ; //实例化对象
类名 对象名称 = new 类名 () ; //创建并实例化对象
访问对象中的属性/方法
访问属性
访问方法
new :实例化
范例
class Person{
String name; //声明姓名属性
int age; //声明年龄属性
public void tell(){ //获取信息方法
System.out.println("name:"+name+",age"+age);
}
}
public class ClassDemo02{
public static void main(String arg[]){
Person per = new Person(); //创建并实例化对象
per.name="张三"; //为name属性赋值
per.age=30; //为age属性赋值
per.tell(); //调用类中的方法
}
}
结果:
姓名:张三,年龄:30
public class Person {
//静态 属性
//全局变量
String name; //只有属性名,没有属性值
int age;
//动态 方法
//吃饭
public void eat(){
String name = “abc”; //局部变量 可以和全局变量重名,并且优先级高,会覆盖全局
System.out.println("吃饭...");
}
//睡觉
public void sleep(){
System.out.println("睡觉...");
}
}
public class TestPerson {
public static void main(String[] args) {
//类 对象 = new 类() ;
Person zs = new Person(); //Person zs;
//zs = new Person();
//对象.属性
zs.name = "张三";
zs.age = 28;
System.out.println(zs.name);
System.out.println(zs.age);
//对象.方法
zs.eat();
zs.sleep();
}
}
/*
张三
28
吃饭...
睡觉...*/
方法 是对个对象共有的
属性 是各个对象独有的
Person zs = new Person();
一般而言,对象是指堆中的东西
栈里面zs的 称为引用
引用
相当于C中的指针。持有对象的内存地址
对象引用传递P101
将一个堆内存空间的使用权给多个栈内存空间,每个栈内存空间都可以修改堆内存的内容
eg:
创建两个对象,为两个对象引用属性之后,
per2 = per1 ;
这时per2指向per1的堆内存,而之前per2所占的堆内存就没有被任何栈内存空间引用了
此时出现垃圾空间
垃圾空间的释放
Java本身提供垃圾收集机制(Garbage Collecting,GC) ,会不定期的释放不用的内存空间,只要对象不使用了,就会等待GC释放空间
一个栈内存空间只能指向一个堆内存空间,要想再指其他的堆内存空间,必须先断开已有的指向才能分配新的。
封装性P103
面对对象的一大特性
所谓封装性,就是对外不可见
一般开发中往往要将类中的属性封装(private)
格式
属性封装
方法封装
eg:
class Person{
private String name;
private int age;
public void tell(){
System.out.println("name:"+name+" age:"+age);
}
}
public class text1 {
public static void main(String[] args) {
Person per = new Person();
per.name = "zs"; //错 ,无法访问封装属性
per.age=-30; //错
per.tell();
}
}
结果:
Error:(11, 12) java: name可以在Person中访问private
Error:(12, 12) java: age可以在Person中访问private
name和age是private的了啦,对象不能直接访问,保证了对口处有所限制。
只要是被封装的属性,则必须通过setter和getter方法设置取得。
来使用一下这个方式叭!
class Person{
private String name;
private int age;
public void tell(){
System.out.println("name:"+name+" age:"+age);
}
public String getName(){
return name; //取得姓名
}
public void setName(String n){
name = n; //设置姓名
}
public int getAge(){
return age; //取得年龄
}
public void setAge(int a){
age = a; //设置年龄
}
}
public class text1 {
public static void main(String[] args) {
Person per = new Person();
per.setName("zs"); //调用setter设置姓名
per.setAge(-30); //调用setter设置年龄
per.tell();
}
}
结果:
name:zs age:-30
在程序中可以发现通过setter和getter方法可以设置和取地属性,而在调用主方法时,也是调用了setter()方法进行的内容赋值。
如果想对设置进去的内容进行检查,也只需要在setter() 方法处加入检查代码即可。
class Person{
private String name;
private int age;
public void tell(){
System.out.println("name:"+name+" age:"+age);
}
public String getName(){ //取得姓名
return name;
}
public void setName(String n){ //设置姓名
name = n;
}
public int getAge(){ //取得年龄
return age;
}
public void setAge(int a){ //设置年龄
if (a>=0 && a<150){ //通过setter 在此处加上验证代码
age = a;
}else{
System.out.println("真的有这个岁数的人类吗???");
}
}
}
public class text1 {
public static void main(String[] args) {
Person per = new Person();
per.setName("zs");
per.setAge(-30);
per.tell();
}
}
结果:
真的有这个岁数的人类吗???
name:zs age:0
tips:
类中全部属性必须封装,封装之后的属性必须通过setter和getter进行访问
用private声明的属性或方法只能在其内部使用,而不能在类的外部被调用
构造方法
为类的属性初始化,在对象实例化时就直接把对象的值赋给属性。
可视为一种特殊的方法
格式
class 类名称{ ** //名称必须与类名称一致
访问权限 类名称(类型1 参数1,类型2 参数2,…){
程序语句;
…. **//构造方法没有返回值
}
}
eg:
class Person{
public Person(){
System.out.println("一个新的Person对象产生咯!");
}
}
public class text1 {
public static void main(String[] args) {
System.out.println("声明对象:Person per = null;");
Person per = null; //声明对象时不调用构造
System.out.println("实例化对象: per = new Person();");
per = new Person(); //实例化对象时调用构造
}
}
结果:
声明对象:Person per = null;
实例化对象: per = new Person();
一个新的Person对象产生咯!
当调用关键字new 实例化对象时才会调用构造方法,只要是类就必定存在构造方法。<br />**P108 **<br />“只要是类就必定存在构造方法” 为什么之前没有构造方法也可以对象实例化?<br />不构造会发生什么?
eg2通过构造方法为类中的属性赋值
class Person{
private String name; //声明姓名属性
private int age; //声明年龄属性
public Person(String name,int age){ //定义构造方法为属性初始化
this.setName(name); //为name属性赋值
this.setAge(age); //为age属性赋值
}
//取得信息的方法tell()
public void tell(){
System.out.println("name:"+getName()+" ,age:"+getAge());
}
public String getName(){ //取得姓名
return name;
}
public void setName(String a){ //设置姓名
name = a;
}
public int getAge(){ //取得年龄
return age;
}
public void setAge(int b){ //设置年龄
if (b<0&&b>150){ //在此处加上验证代码
System.out.println("我怀疑你出错了并且有足够的证据!");
}else{
age = b;
}
}
}
public class text1{
public static void main(String[] args){
Person per = new Person("zs",30); //调用构造方法,传递两个参数
per.tell();
}
}
结果:
name:zs ,age:30
eg3构造方法也可以重载P110
匿名对象
没有明确给出名称的对象
一般匿名对象只使用一次,只在堆内存中开辟空间,不存在栈内存引用
所以说匿名对象实际上就是一个堆内存空间,对象不管是匿名还是非匿名,都必须在开辟堆内存空间之后才能使用。
定义格式
eg
class Person{
private String name;
private int age;
public Person(String name,int age){
this.setName(name);
this.setAge(age);
}
public void tell(){
System.out.println("name:"+getName()+" ,age:"+getAge());
}
public String getName(){
return name;
}
public void setName(String a){
name = a;
}
public void setAge(int b){
if (b<0&&b>150){
System.out.println("我怀疑你出错了并且有足够的证据!");
}else{
age = b;
}
}
public int getAge(){
return age;
}
}
public class text1{
public static void main(String[] args){
new Person("zs",30).tell(); //匿名对象
}
}
主方法中可以发现,直接使用了 new Person(“zs”,30) 语句,这实际上就是一个匿名对象
节省内存,此处没有任何栈内存引用它,所以此对象使用一次之后就等待被垃圾收集机制回收。
?匿名对象的作用
方法的调用 常见情况
同一个类中:
都有static,或都没有static,或没的调有的:直接调用
有static** 不能直接调用没有static的方法**
静态方法
public static void eatFruit(){…}
非静态方法
public void eatFruit(){…}
public class Person2 {
//属性
//方法
public void eatFruit(){
System.out.println("吃水果..");
}
public void eatFood(){
System.out.println("吃主食..");
eatFruit(); //调用eatFruit方法
}
public void sleep(){
}
public static void main(String[] args) {
Person2 p = new Person2();
p.eatFood(); //调用eatFood方法
}
}
不在同一个类中:
万能方法:new 对象,对象.方法();
Person2 p = new Person2();
p.eatFruit();
调用的另一个方法必须是静态的(有static)
类名.方法()
Person2.eatFruit();
public class Person3 {
public void aa() //public void static aa()
{
Person2 p = new Person2();
p.eatFruit();
Person2.eatFruit(); //类名.方法() 其中的方法必须是static修饰的
}
public void bb()
{
}
public static void main(String[] args) {
Person3 p = new Person3();
p.aa();
}
}
static方法 是 类级别的 属于类
非static方法 是 对象级别 ,属于对象
对象.static方法() | 对象.非static方法()
类.static方法()
类有的,对象自然有
对象有的,类不一定有