面向对象第二天(面向对象的三大特征)
补充(构造方法)
构造方法:构造器,构造函数,构建器-----------------------完成对对象数据的初始化
- 作用:给成员变量赋初始值.
- 语法:和类同名,但参数列表不同(就是方法的签名不一样),没有返回值类型,连void也没有
- 调用:在创建对象的时候,也就时new一个对象的时候,java会自动调用
- 若是自己不写构造方法,则系统默认创建一个构造方法,若是自己写了一个构造方法,则系统不在默认提供
构造方法可以重载
this:指代当前对象,哪个对象调用方法它指的就是哪个对象
只能用在方法中,方法中访问成员变量之前默认有个this.
this的用法:
- this.成员变量名-----------------------访问成员变量
注意:当成员变量与局部变量同名时,若想访问成员变量,则this不能省略- this.方法名()----------------------------调用方法(一般不用,了解即可)
- this()--------------------------------------调用构造方法(一般不用,了解即可)
一、封装
封装其实就是将一些共有的都装到一个盒子中,然后留一个出口以便外界访问。
类:封装的是一些共有的属性和行为。
访问控制修饰符:封装的是具体的访问权限
/** 封装类的演示 */
class Student(){
/**学生共有的特征/属性 名字和年龄
private 私有 这里修饰age表示年龄只能在本类中访问
public 公共的 这里修饰名字表示name可以在任何类访问
*/
private int age;
public String name;
//学生共有的行为
void study(){
System.out.println("学生在学习!")
}
void rest(){
System.outPrintln("学生在休息!")
}
/*age不可能只在本类中使用,那么该怎么办?
这里就要使用到get和set方法了,以下代码实现了私有化属性的调用
*/
public void setAge(int age){
/*这里从外面接收到一个参数,为了见名知意,所以这里参数名和变量名
取了一样的名字,为了区分,java提供了this关键字代表引用对象的变量*/
this.age = age;
}
public int getAge(){
//这里将age传出去,以便外界访问
return this.age;
}
}
封装的优点:
1)提高了程序的安全性,保护了数据
2)提高了程序的可维护性
3)隐藏了代码的实现细节
4)统一了接口
二、继承
我们在封装的时候说过我们会将一些共有的特征封装在一个类中,我们将这个类称为父类也叫做超类,我们想要去调用这些属性和行为就需要去继承它,那么这些类我们称为子类,也叫做派生类.
继承的优点:通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。
/** 继承代码的演示 */
class void Aoo(){
//我们创建一个父类,其中我们有两个属性a和b,一个move()行为
int a;
int b;
void move(){
System.out.println("父类在移动!");
}
}
public class Boo extends Aoo {
//创建一个子类Boo继承Aoo
void move(){
System.out.println("子类在移动!");//这里发生了重写
super.move();//这里super可用用来调用父类的方法
System.out.println(super.a);//super还可以调父类的成员变量
}
}
public class Demo {
public static void main(String[] args) {
Aoo a = new Aoo();//创建Aoo对象,
a.move();//父类在移动
Boo b = new Boo();//创建Boo对象
//这里子类重写了父类的move方法
b.move();//子类在移动 父类在移动 5
}
}
- 在派生类的构造方法若没有调用超类构造方法,则默认super()调用超类的无参构造方法
- 在派生类的构造方法中若自己调用了超类构造方法,则不再默认提供
super关键字:
- super:指代当前对象的超类对象
- super.成员变量名----------------------------访问超类的成员变量
- super.方法名()---------------------------------调用超类的方法
- super()-------------------------------------------调用超类的构造方法
3.多态
多态其实就是对象或方法的多种形态,是面向对象的第三个特征,其建立在另外两个特征(封装和继承)的基础之上的
/** 多态演示 */
//定义一个Person父类
public class Person {
//Person 类封装了一些特定的行为和方法
public class Person {
int age;
String name;
void work(){
System.out.println("在干神马?");
}
}
//定义一个子类
public class Student extends Person{
//子类继承了父类,可以重写work方法
void work(){
System.out.println(name+"在学习!");
}
}
//定义一个子类
public class Teacher extends Person{
//子类继承了父类,可以重写work方法
void work(){
System.out.println(name+"在上课!");
}
}
//定义一个演示类
public class PersonDemo {
public static void main(String[] args) {
//一个Person的引用指向了一个学生类
Person p = new Student();
p.age = 18;
p.name = "curry";
p.work();//输出:curry在学习!
//一个Person类引用指向了一个老师类
Person t = new Teacher();
t.age = 28;
t.name = "James";
t.work();//输出:James在上课!
}
}
上述代码就体现了多态,一个Person可以有老师和学生这两种形态
同时也体现多态的一个用法:向上造型
向上造型:
- 父类 引用 =new 子类对象
- 注意:编译看左边类型,运行看右边类型
- 子类可以调用父类的方法和成员变量(需要注意一下访问权限).
上面我们说了向上造型,但是向上造型的缺点也特别缺点明显,子类访问不了自己的方法,但是我们就是想要使用子类的数据那么该怎么办呢?
其实我们在学习Java基础,数据类型就已经接触过了,当时我们在大类型转小类型时学习了一种方法也就是强行转换,那么在这我们同样也可以实现这种方法,即向下造型:下面看代码
public class Student extends Person{
//我们在Student添加一个play
void work(){
System.out.println(name+"在学习");
}
void play(){
System.out.println(name+"三分球贼拉准!");
}
}
public class PersonDemo {
public static void main(String[] args) {
Person p = new Student();
p.age = 18;
p.name = "curry";
p.work();
// p.play(); //编译错误,因为父类中不存在play方法,属于子类特有的方法
Person t = new Teacher();
t.age = 28;
t.name = "James";
t.work();
//子类类型 引用= (子类类型) 父类引用
Student p1 = (Student) p;
p1.play();//输出curry三分贼拉准!
//Student p2 = (Teacher) t //这里会发生编译错误
//Person p2 = (Student) t; //这里虽然不会发生编译错误,但会发生ClassCastException,类型转换异常
//为了防止出现ClassCastException异常,我们一般会在转换之前进行一次判断,如果父类引用和转换的类型一样或被被继承在转换
if (t instanceof Student){
Person p2 = (Student) t;
}
}
}
所以要满足向下造型需要两个条件:
- 引用所指向的对象,就是该类型
- 引用所指向的对象,继承了该类型
以上仅供参考,本人小白一个,希望有错误的地方可以指出来…