1.构造方法:一般用于初始化成员变量
public class Person {
private String name;
private int age;
//定义空参构造方法
public Person() { //1.构造函数名必须和类名一致
//2.没有返回值定义
//3.可以有形参
System.out.println("空参构造方法被调用了!");
}
//定义满参构造方法
public Person(String name,int age) {
System.out.println("满参构造方法被调用了!");
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
Person p = new Person(); //去调用空参的构造方法
p.setName("高亮亮");
System.out.println(p.getName());//高亮亮
System.out.println(p.getAge()); //0
Person p2 = new Person("柳岩",32);//找Person(String,int)的构造方法
System.out.println(p2.getName());//"柳岩"
System.out.println(p2.getAge());//32
}
注意事项:
1.在一个空类中有默认构造方法
public 类名(){
}
2.如果在类中定义了构造方法,就不再有默认构造,如果想使用,必须手动添加
2.super与this
public class Person {
private String name;
private int age;
//定义空参构造方法
public Person() { //1.构造函数名必须和类名一致
//2.没有返回值定义
//3.可以有形参
System.out.println("空参构造方法被调用了!");
}
//定义满参构造方法
public Person(String name,int age) {//name="刘亦菲" age=28
System.out.println("满参构造方法被调用了!");
this.name = name;//this.name="刘亦菲"
this.age = age;//this.age=28
}
public String getName() {
return name;
}
}
public class Coder extends Person{
public Coder() {
//super();//在初始化子类成员变量之前,先去调用父类的空参构造
//隐含创建父类Person对象,一旦在堆中创建好对象
//那么Person的属性age和name就有默认值,那么子类就可以获取或者设置父类的属性值
System.out.println("子类的空参构造");
}
public Coder(String name,int age) {//name="刘亦菲" age=28
//手动调用父类的非空参构造
super(name,age);//super("刘亦菲",28)
//如果不写super(name,age); 默认有super();
}
}
Coder coder2=new Coder()
coder2.getName();
Coder coder = new Coder("刘亦菲",28);
System.out.println(coder.getName());//刘亦菲
注意事项:接口没有构造方法,抽象类有构造方法(抽象类自身不能创建对象,但是可能有一些属性,当创建子类对象的时候,可以通过super语句初始化父类成员)
this关键字与this语句:
this关键字:
1.区分成员变量与局部变量
2.在成员方法中this指向调用该方法的对象
this语句:
1.调用本类的其它构造方法
super关键字与super语句:
super关键字:
super关键字可以在子类中调用父类的非private修饰的成员(成员变量和成员方法)
super语句:
在子类的构造方法中调用父类的相应的构造方法
this语句和super语句都必须方法在第一行,两者只能存在其一
3.多态(多种形态):
a.父类引用指向子类对象
父类: 人
人的一生角色:儿子 学生 男朋友 丈夫 父亲 爷爷 太爷....
Person person=new Student("张洪慊");//张洪慊这个学生是一个人
Person person=new BoyFriend("班长");//班长这个男朋友角色是一个人
Student student =new Person();//人是一个学生(人不一定是一个学生,可能还是医生,IT男....)
类定义:
public class Person{
public void method(){
System.out.println(“一个普通方法”);
}
}
public class Student extends Person{
public void method(){
System.out.println(“一个被重写的方法”);
}
public void method2(){
System.out.println(“一个干扰方法”);
}
}
类使用:
Student s = new Student();
s.method();//编译时期:会去找Student类中有没有method()方法,有编译通过,没有编译失败
//运行时期:找student所属的类中有没有method()方法,有直接运行,没有报错
//编译时期看=左边,运行看等号右边
Person p = new Student();
p.method();//先找Person类,有method()方法,编译通过,运行时执行Student类中method()方法
p.method2(); // 先找Person类,有method2()方法,直接编译报错
b.自动类型提升与强制向下转型
class Animal{
public void eat(){
System.out.println("吃东西");
}
}
class Dog extends Animal{
@Override
public void eat(){
System.out.println("吃骨头");
}
public void lookHome(){
System.out.println("看家");
}
}
Animal animal=new Dog();//自动类型提升(子类型->父类型)
//狗是一只动物
animal.eat();//吃骨头
//animal.lookHome();//编译时,animal中没有lookHome()编译报错
Dog dog=(Dog)animal;//强制向下转型(父类型-->子类型)
//运行时期代码相当于:Dog dog=(Dog)(new Dog());
//把狗又叫成一只狗,没问题
dog.eat();//吃骨头
dog.lookHome();//看家
Animal animal=new Animal();
//Dog dog=(Dog)animal;//编译时期:dog和animal构成父子关系可以向下转型
//运行时期:Dog dog=(Dog)(new Animal());
//动物是一只狗(错误,动物还可能是猫,鳄鱼...)
//报错ClassCastException
1.多态自始至终操作的都是子类的对象
2.强制向下转型目的为了使用子类特有的方法
c.final与static关键字
1.final:
a.可以修饰变量,被修饰变量就变成了常量,并且只能被赋值一次
public static final double PI=3.1415926//PI是个固定的值,我们可能会忘掉
//用PI常量存储,直接通过Math.PI来使用
final Person p=new Person();//p的地址值不能被重新赋值,p自始至终都指向Person对象
b.final修饰的方法不能被子类重写
c.final修饰的类不能被继承
2.static:
a.被静态修饰的非private修饰的成员变量或成员方法,可以在类外通过 类名.静态变量 或 类名.静态方法(传参)
b.静态成员随着类的加载而加载,静态成员存放在方法区,此时很可能没有创建对象
因此静态成员可以直接通过类名访问
静态方法没有this和super关键
c.静态变量当加载到方法区就有默认值
非static修饰成员变量当创建该类的对象的时候才有默认值
d.静态成员被所有的对象共享一份
d.内部类
1.匿名(无名)内部类/匿名子类对象
new 父类/父接口(){
//重写或者实现父类/父接口中的方法
};
//创建一个无名的子类
//创建该无名的子类的对象
class Animal{
public void eat(){
System.out.println("吃东西");
}
}
Animal animal=new Animal(){//定义一个Animal的无名子类,同时创建该子类的对象
public void eat(){ //可以把这个Animal的无名子类对象给了父类Animal引用
System.out.println("吃未知的东西");
}
};
2.成员内部类:定义在成员位置上,可以访问外部类中的成员
3.局部内部类:定义在方法的内部,可以访问外部类中的成员
e.匿名对象
new 类名();//每写一次匿名对象都是一个新的对象
f.局部内部类访问局部变量需要加final修饰
interface Father {
public abstract void function();
}
// 外部类
class Outer {
public Father method() {//Father father=new Son();
final int i=10;//如果不加final修饰,当method()方法被执行完
//局部变量i要被销毁,当使用father.function();调用Son类中function
//int i=10; //无法访问i,加上final,即使method()执行完毕i也不会被销毁,因为i已经变成常量存储在常量池中,延长i的生命周期
class Son implements Father {
public void function() {
System.out.println(i);
}
}
return new Son();
}
}
class FinalVariable {
public static void main(String[] args) {
Outer out = new Outer();
Father father = out.method();
father.function();
}
}
|
|