一:static关键字的使用介绍与注意事项
1.1static的特点:
- 随着类的加载而加载
- 优先于对象存在。因为在还没有new对象的时候static修饰的变量或者方法已经加载完成存放在静态方法区中。
- static关键字不能与this共存。因为:this代表的是当前类的对象。
class staticDemo1{
static int age;
public static void test(){
int a= staticDemo1.age;
System.out.println(a);
}
}
public class staticDemo {
public static void main(String[] args) {
// static修饰的变量与方法不建议创建对象来调用
// staticDemo1 s = new staticDemo1();
// s.test();
// 建议使用类名.变量或者方法来使用
staticDemo1.test();
}
}
- 如上所示:如果编译时静态变量没有出示话数据的话,编译时默认赋值为“0”
- 被静态修饰的 可以被多个对象共享:有共享共用的意思
1.2注意:
- static修饰的变量与方法建议使用类名.静态变量/方法,直接使用
- static关键字不能与this共同使用。this代表当前类的对象
的地址值(类似创建的对象。但是static优先于new(创建对象)所以不能共同使用)。
二:代码块的先后顺序问题
2.1 代码块的定义
程序中没有连接方法由{}包括的代码。
2.2代码块分类主要包含以下几种。
- 局部代码块
- 构造代码块
- 静态代码块
2.3代码块的执行优先顺序
静态代码块 > 构造代码块 > 局部代码块
三:继承
继承是java三大特性之一,继承就是将多个类有相同属性(方法)抽取到一个独立的类中,然后这个独立类与这多个类禅城关系–继承
3.1继承优点:
- 易维护
- 提高代码的复用性;
- 继承是多态的前提条件
例子:
class people{
private String name;
private int age;
private String gender;
public people(){}
public people(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
//无参构造
public String getName() {
return name;
}
//有参构造
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
//特有方法
public void eat(){
System.out.println(name+age+gender+":喜欢吃巧克力");
}
}
public class extendsDemo extends people{
public extendsDemo() {
}
public extendsDemo(String name, int age, String gender) {
super(name, age, gender);
}
public static void main(String[] args) {
people p = new people("张三", 28, "男");
p.eat();
}
}
3.3继承的特点
- java语言中继承只支持单继承不支持多继承,但是支持多层继承
3.4继承书写的格式
- 书写的格式是:class 类名 extends 父类{}
3.5继承中的关键字
- estends:子类继承父类的关键字
- super:在子类中指向父类对象地址,相当于new 一个父类
3.6 继承中的注意事项
- 子类继承父类,只能继承公共的属性与公共的方法。私有的属性与私有的方法不能被外界访问,只能通过公共的方法get/set进行间接的访问
- 父类的构造方法不能继承,子类可以使用super关键字进行访问
- 子类的成员变量与父类的成员变量如果一致的情况下,遵循就近原则
- 子类继承父类则默认访问的是 **无参构造 **(Zi Zi = new Zi();)。如果需要访问有参构造则需要在new对象后的()添加具体的参数。
- 子类肯定会使用父类的属性方法,所以在子类的构造方法中第一行隐藏了 super();先给父类初始化数据。
- 父类如果没有构造方法,则子类所有的构造方法都会报错
3.7继承中的缺点
- 降低代码的灵活性。子类必须拥有父类的属性和方法,让子类自由的世界中多了些约束;
- 增强了耦合性。当父类的常量、变量和方法被修改时,需要考虑子类的修改,而且在缺乏规范的环境下,这种修改可能带来非常糟糕的结果——大段的代码需要修改。
3.8方法重写与方法重载
- 方法重载:1)方法名一致;2)形式参数列表不同(个数、类型)
- 方法重写:在继承关系中,子类出现了父类一模一样的方法声明
- 重写的目的:子类有自己的功能,需要将父类的该功能覆盖掉!
四:多态
多态就是一种事务在不同时间体现出不同的形态就叫多态。
4.1多态的前提条件
- 具有继承关系extends
- 需要存在方法的重写
- 必须是父类指向子类对象
4.2格式
向上继承:
格式: Fu fu = new Zi() ;
向下继承:父类想使用子类的方法则需要向下转型
格式: Zi zi = (Zi)fu;
多态中(向下转型使用不当,会出现ClassCastException异常)
4.3多态的特点
- 针对成员变量的访问:编译看左运行看左
- 针对成员方法的访问:编译看左运行看右
- 如果成员方法是静态static 方法:编译看左运行看左
- 构造方法:需要先初始化父类的构造方法然后再初始化子类。分层初始化
4.4 多态的好处
- 提高代码的复用(由继承保证)
- 提高了代码的扩展性(由多态保证)
4.5 多态中的关键字 final
- 修饰变量:变量被fianl修饰后,如果一经赋值则不能更改
- 修饰方法:该方法不能被重写
- 修饰类:该类不能被继承(该类对象的地址值不会改变)
class People{
private String name;
private int age;
private String gender;
final String nationality ="中国";
public People(){}
public People(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
//特有的方法
public static void eat(){}
public void sleep(){}
public final void study(){
System.out.println("学习");
}
}
class student extends People{
public student() {}
public student(String name, int age, String gender) {
super(name, age, gender);
}
@Override
public void sleep() {
System.out.println("这个是子类的睡觉");
}
public void goToSchool(){
System.out.println(this.getName()+getAge()+"岁"+getGender()+super.nationality+"去上学");
}
}
//测试类
public class finalDemo {
public static void main(String[] args) {
// 通过有参构造进行数据初始化,父类指向子类对象。
// 向上转型
People p = new student("学生" ,35 , "女");
p.sleep();
// 向下转型访问子类特有的方法
student s= (student)p;
s.goToSchool();
}
}
五:抽象类
现实中对一个群体的总结描述,例如中国人-陕西人-西安人-雁塔人
5.1 抽象关键字:abstract
该关键字可以适用于类、方法
方法中使用格式:
权限修饰符(一般情况都是public) abstract 返回值类型 方法名(形式参数列表)
类中使用格式:
abstract class 类名{}
5.2抽象类的特点
- 抽象类中不一定有抽象方法,但是有抽象方法的一应是抽象类
- 抽象方法是没有方法体的,需要继承的子类重写父类方法来实现该方法
- 抽象类是不能被实例化的。
- 抽象类实例化的方式:父类抽象类指向子类对象。Fu fu =new Zi();
5.3抽象方法的宗旨是
强制子类重写父类方法,具体功能子类实现。如果子类不重写父类的抽象方法,则子类会报错。非抽象方法可以不用重写
//父类
public abstract class people {
private String name;
private int age;
private String gender;
public people(){}
public people(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public abstract void sleep();
}
//教师类
public abstract class teacher extends people{
private String occupation;//职业
public teacher() {
}
public teacher(String occupation) {
this.occupation = occupation;
}
public teacher(String name, int age, String gender, String occupation) {
super(name, age, gender);
this.occupation = occupation;
}
public String getOccupation() {
return occupation;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
@Override
public void sleep() {
System.out.println("教师也需要睡觉");
}
public abstract void eat();
}
//高中老师类
public class highSchoolTeachers extends teacher {
public highSchoolTeachers() {
}
public highSchoolTeachers(String occupation) {
super(occupation);
}
public highSchoolTeachers(String name, int age, String gender, String occupation) {
super(name, age, gender, occupation);
}
@Override
public void eat() {
System.out.println("高中老师也需要吃饭");
}
public void selfIntroduction(){
System.out.println("大家好!我是:"+getName()+"\n"+"今年"+getAge()+"岁了。我的职业是"+"\""+
getOccupation()+"\"");
}
}
//测试类
public class testDemo {
public static void main(String[] args) {
teacher t = new highSchoolTeachers("高圆圆", 32, "女", "高中老师");
t.sleep();
t.eat();
//向下转型调用子类特有方法
highSchoolTeachers h= (highSchoolTeachers)t;
h.selfIntroduction();
}
}
六:接口
6.1什么是接口?
接口就是一个现实事物所具有的额外的功能
6.2定义格式:
interface 接口名
接口名遵循标识符命名规则:大驼峰命名法
6.3接口的方法:
接口的方法中没有方法体,全部是抽象方法。强制实现接口方法的子类重写。
6.4接口的特点:
- 不能实例化
- 实例化需要实现类进行实例化(接口多态)。
- 实现接口方法的是抽象类的话,接口实例化需要指向该抽象类的具体的子类。
- 实现子类与接口的关系是:implements
6.5 实现类的格式是: 权限修饰符 class 类名 implements 接口名{}
interface Fly {
public abstract void getFly();
}
abstract class birdImpl implements Fly{
public birdImpl() {}
@Override
public abstract void getFly();
}
class eagle extends birdImpl{
public eagle() {
}
@Override
public void getFly() {
System.out.println("鹰会飞");
}
public void eat() {
System.out.println("鹰会抓兔子吃");
}
}
public class interfaceDemo {
public static void main(String[] args) {
// 实例化接口多态。接口实例化需要子类实现接口,子类为具体的类
// eagle继承于birdImpl抽象父类,所以接口实例化需要指向具体实现子类的对象
Fly f=new eagle();
f.getFly();
// 父类没有子类特有的功能,需要向下转型才能访问
eagle e= (eagle)f;
e.eat();
}
}
接口的成员特点:
- 变量:变量默认被public static final修饰,成为常量
- 方法:默认被 public abstract 修饰,可以省略默认修饰
- 构造方法:没有构造方法
6.6接口与抽象类的区别:
- 变量: 接口中只能定义常量,抽象类中可以定义常量也可以定义变量
- 方法: 接口中只能有抽象方法,具体实现需要实现子类重写方法。抽象类中可以有抽象方法也可以有实际的具体方法
- 构造方法: 接口中没有构造方法,抽象类中有构造方法。
- 与子类之间的关系: 接口的子实现类是实现接口的,关键字是implements;继承的关键字是extends
- 设计理念:
1. 抽象类—>不能实例化—通过具体的子类实例化---->存在继承关 系,体现的是一种 "is a"的关系
2. 接口---->不能实例化—>通过具体的子实现类实例化---->谁如果实现了接口,就具备额外的功能,
体现的是一种"like a"的关系