类和对象
类和对象的关系
类是具有相同属性和方法的一组对象的集合。
1. 从语义上理解:类是用于创建对象的模板,是一个抽象的概念,而对象是类的一个实例。
2. 从语法上理解:类是我们自定义的一种数据类型,而对象则是这种数据类型的变量。
类的定义
public class 类名{
访问修饰符 类型 属性名 //成员变量,也叫全局变量
访问修饰符 返回值类型 方法名(参数类型 参数){
访问修饰符 类型 属性名 //局部变量
*方法体*
}
类的方法
- 多个方法不能相互嵌套定义;
- Return只能返回一个值,且表示方法结束;
- 对于引用数据类型,方法传递的是复制的地址;而对于简单数据类型,方法传递的是复制的数据。
例子:
public class StudentTest {
public static void main(String[] args) {
Student zhangsan=new Student();
zhangsan.student(18,"zhangsan","Mr.Li");
System.out.println(zhangsan.name);
Student lisi=new Student();
lisi=zhangsan;//将存放zhangsan.name的地址复制一份给lisi
if(lisi.name==zhangsan.name){//lisi.name的地址就和zhangsan.name的地址指向同一个堆内存
System.out.println("1");
}
lisi.name="lisi";
System.out.println(zhangsan.name);
int j=0;
int i=j;//将j中的数据复制一份给i,当中的数据改变时,j中数据不受影响
i++;
System.out.println("j="+j);
System.out.println("i="+i);
}
}
- 方法可变参数,只允许传入的最后一个参数为可变参数
public void function(int... is) { //要把is理解为一个int数组
for (int i = 0; i < is.length; i++) {
System.out.print(is[i]+" ");
}
}
对于可变参数,适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理,且可变参数必须放在方法参数的最后。
可变参数的特点:
①只能出现在参数列表的最后;
②…位于变量类型和变量名之间,前后有无空格都可以;
③调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中一数组的形式访问可变参数。
对象的创建和使用
- 创建对象:类名 对象名=new 类名();
- 使用对象:
对象名.属性;
对象名.方法();
举例
写一个Person类
public class Person {
int age;
String name;
String sex;
public Person(int age1,String name1,String sex1){
age=age1;
name=name1;
sex=sex1;
}
public String eat(String food){
System.out.print("你只会吃"+food);
return food;
}
public void sleep(){
System.out.println(",还有睡觉觉!");
}
}
写一个测试类
public class Test {
public static void main(String[] args) {
Person zhangsan = new Person(18, "张三", "男");
System.out.println("你叫" + zhangsan.name + " 性别" + zhangsan.sex + " 今年" + zhangsan.age + "岁");
zhangsan.eat("饭");
zhangsan.sleep();
}
}
输出结果为:
变量的初始化
成员变量可以只声明,不初始化;但局部变量必须要初始化。
不同数据类型的默认值:
1. 基本数据类型:
byte(0),short(0),int(0),long(0L),float(0.0F),double(0.0),boolean(false),char(’ ‘)
2. 引用数据类型的默认值都为:null
类的封装
目的为保护私有属性,添加get()和set()方法来对属性进行封装,提高了程序的可复用性和可维护性,降低了程序员保持数据与操作内容的负担。
①修改访问修饰符—>private
②创建get()和set()方法—>用于属性的读写
③在方法内加入控制语句—>对属性值得合法性进行判断
public class Student{
private int stuNo;
public int getStuNo(){
return stuNo;
}
public void setStuNo(int stuNo){
this.stuNo=stuNo;
}
}
构造方法
构造方法:负责对象成员的初始化工作,为实例变量赋予合适的初始值。
语法:①方法名和类名相同;②没有返回类型
【注意】
1. 使用new关键字调用构造方法,在我们创建类的实例时会自动调用。
2. 一个类可以没有构造方法(系统有隐藏的无参构造方法),也可以有多个构造方法,它们构造重载关系。
3. 如果我们定义了有参构造方法,就会自动覆盖掉系统无参的构造方法。
4. 构造方法不能被继承。
方法的重载(overload)
条件:①在同一个类中存在两个以上的同名方法②方法参数不同(参数的数目不同或参数类型的组合不同)③与访问修饰符和返回值的类型无关
继承
- 继承需符合的关系:”is-a“,父类更通用,子类更具体
子类具有父类的一般特性(包括属性和方法),以及自身特殊的特性。 - 继承使用extends关键字,子类只能继承父类的属性和方法,不能继承父类的构造方法
- 继承的初始化顺序:先父类的属性,后父类的构造方法,然后先子类的属性,后子类的构造方法。
super关键字
- 调用父类的属性:super.属性;
- 调用父类的方法:super.方法();
- 子类会默认调用父类的无参构造方法(super(),可以省略不写),若父类有有参构造方法(super(参数),不能省略,且必须放在子类构造方法的第一行)。
this关键字
this关键字表示调用该类实例化的对象
- this.属性名:调用该对象的属性
- this.方法名:调用该对象的方法
- this():调用本类中的另一个构造方法,且必须写在第一行
方法的重写(override)
- 在继承关系的子类中
- 重写的方法名,参数,返回值类型必须与父类相同
- 私有方法不能被继承,因而也无法重写
- 重写方法的访问修饰符的权限要比父类的权限大或者相同
访问修饰符的权限
封装类
把简单数据类型封装为引用数据类型
1. 自动装箱
Integer i =10;
相当于:Inerger i = new Inerger(10);
2. 自动拆箱
int i = new Inerger(10);
相当于:int i =10
综合的例子
创建一个Dog类
public class Dog {
String color="红色";//可以被子类调用
public Dog(String s){
System.out.println("调用了父类的构造方法");
}
public void run(){
System.out.println("它们都会跑");
}
}
创建一个Jinmao子类
public class Jinmao extends Dog{
public String weiba;
String myColor=super.color;
public Jinmao(){
super("");//调用父类的有参构造方法,且必须放在第一句
System.out.println("子类自己的构造方法"+" 子类调用父类的属性"+myColor);
}
public Jinmao(int a){
this();//调用子类的另一个构造方法
}
public void run(){ //重写了父类的run方法
this.weiba="长";
System.out.println("父类方法的重写:我还会卖萌的跑!");
super.run(); //调用父类的方法
}
public void run(int a){ //方法的重载
System.out.println("方法的重载"+a);
}
}
创建一个测试类
public class test {
public static void main(String[] args){
Jinmao jm = new Jinmao();//运行子类无参的构造方法
jm.run(); //调用子类的run方法
jm.run(1); //调用了子类的重载的run方法
Jinmao jm2 =new Jinmao(1);//运行子类有参的构造方法
}
}
输出结果: