static的作用:用来区别字段,方法,内部类,初始化代码块是属于对象还是属于类本身。
static修饰符的特点:
1.static修饰的成员(字段/方法),随着所在类的加载而加载.
当JVM把字节码加载进JVM的时候,static修饰的成员已经在内存中存在了.
2.优先于对象的存在.
对象是我们手动通过new关键字创建出来的.
3.satic修饰的成员被该类型的所有对象所共享.
根据该类创建出来的任何对象,都可以访问static成员.
4.直接使用类名访问static成员
因为static修饰的成员直接属于类,不属于对象,所以可以直接使用类名访问static成员.
例子:
class PersonDemo
{
public static void main(String[] args)
{
Person p1 = new Person();//创建新对象
System.out.println("人的总数是"+Person.num);//静态字段可以使用类名直接访问
p1.die();//对象调用方法
System.out.println("人的总数是"+Person.num);//静态字段可以使用类名直接访问
p1.birth();//调用方法
System.out.println("人的总数是"+Person.num);//静态字段可以使用类名直接访问
}
}
class Person
{
int age;
String name;
static int num = 5;//静态的字段
void die()
{
System.out.println("去世");
num--;
}
void birth()
{
System.out.println("出生");
num++;
}
}
this关键字代表是对象的引用。也就是this在指向一个对象,所指向的对象就是调用该函数的对象引用。
this主要存在于两个位置:
构造方法中:就表示当前创建的对象.
方法中:哪一个对象调用this所在的方法,那么此时this就表示哪一个对象.
static不能和this一起使用:
当字节码被加载进JVM,static成员以及存在了.
但是此时对象还没有创建,没有对象,就没有this.
使用this:
1.解决成员变量和参数(局部变量)之间的二义性,必须使用;
2.同类中实例方法间互调(此时可以省略this,但是不建议省略)。
3.将this作为参数传递给另一个方法;
4.将this作为方法的返回值(链式方法编程);
5.构造器重载的互调,this([参数])必须写在构造方法第一行;
6.static不能和this一起使用;
当字节码被加载进JVM,static成员以及存在了.但是此时对象还没有创建,没有对象,就没有this
class thisDemo
{
public static void main(String[] args)
{
Person p = new Person();
p.setName("zhangsan");
System.out.println(p.getName());
Student s = new Student("lisi",11);
System.out.println(s.name+s.age);
}
}
class Person
{
private String name;//名字
private int age;//年龄
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;
}
}
class Student
{
String name;
String gender;
int age;
//构造函数相互调用
Student(String name) {
this.name = name;
}
//构造函数相互调用
Student(String name,int age) {
this(name);
//表示调用上面的String的构造器
this.age = age;
}
}
class Single {
//在类中创建一个私有的本类对象
private static Single s = new Single(); // 饿汉式
private Single() { //将构造函数私有化
}
//提供一个用类名调用的公有方法获取该对象。
public static Single getInstance() {
return s;
}
}
class Single2 {
private static Single2 s = null; // 懒汉
private Single2() {
}
public static Single2 getInstance() {
if (s == null) {
s = new Single2();
}
return s;
}
}
解决一个类在内存中只存在一个对象,想要保证对象的唯一
1 为了避免其他程序过多的建立该类对象。禁止其他程序建立该类对象。
2 为了其他程序可以访问该类对象,在本类中自定义一个对象。
3 方便其他程序对自定义类的对象的访问,对外提供一些访问方式。
代码:
1将构造函数私有化
2在类中创建一个私有的本类对象
3提供一个用类名调用的公有方法获取该对象。
super关键字作用
1:主要存在于子类方法中,用于指向子类对象中父类对象。
2:访问父类的属性
3:访问父类的函数
4:访问父类的构造函数
super注意:
this和super很像,this指向的是当前对象的调用,super指向的是当前调用对象的父类。Demo类被加载,执行main方法,Son.class加载,发现有父类Father类,于是Father类也加载进内存。类加载完毕,创建对象,父类的构造方法会被调用(默认自动无参),然后执行子类相应构造创建了一个子类对象,该子类对象还包含了一个父类对象。该父类对象在子类对象内部。this super只能在有对象的前提下使用,不能在静态上下文使用。
class Student
{
String name;
Student()
{
System.out.println("父类无参构造器");
}
}
class Tercher extends Student
{
String name;
Tercher()
{
super();//调用父类无参构造器
System.out.println("子类无参构造器");
}
}
1:描述一个学生类
1:姓名年龄学号属性,学习的方法
2:描述一个工人类
3:姓名年龄工号属性,工作的方法
4:描述一个人类
5:姓名年龄属性,说话的方法。
发现学生类和人类天生有着联系,学生和工人都是人。所以人有的属性和行为学生和工人都会有。出现了代码重复.
//存在的代码的重复的问题
/*
class Tercher
{
String name; //存在的代码的重复的问题
int age;
public void sleep(){}//存在的代码的重复的问题
}
class Student
{
String name;// 存在的代码的重复的问题
int age;
public void sleep(){}//存在的代码的重复的问题
}
class Emyloyee
{
String name;// 存在的代码的重复的问题
int age;// 存在的代码的重复的问题
public void sleep(){}//存在的代码的重复的问题
}
*/
//继承案例
class Person
{
String name;
int age;
public void sleep(){}
}
class Tercher extends Person //继承人类 拥有人类的方法功能 提高代码复用性
{
String level;//级别
}
class Student extends Person //继承人类 拥有人类的方法功能 提高代码复用性
{
String sn;//学号
}
继承关系的作用:
1):解决了代码的重复问题.
2):真正的作用,表示出一个体系.
语法格式:
在定义子类的时候来表明自己需要拓展于哪一个父类.
public class 子类类名extends父类类名
{
编写自己特有的状态和行为
}
方法覆写的原则(一同两小一大):Override
1.实例方法签名必须相同。 (方法签名= 方法名 + 方法的参数列表) 2.子类方法的返回值类型是和父类方法的返回类型相同或者是其子类。 3.子类可以返回一个更加具体的类. 4.子类方法声明抛出的异常类型和父类方法声明抛出的异常类型相同或者是其子类。
@Override标签:若方法是覆写方法,在方法前或上贴上该标签, 编译通过,否则,编译出错。
方法覆盖解决的问题: 当父类的某一个行为不符合子类具体的特征的时候,此时子类需要重新定义父类的方法,并重写方法体.
class OverrideDemo
{
public static void main(String[] args)
{
//创建一个对象
Penguin p = new Penguin();
p.fly();
}
}
//鸟
class Bird
{
public void fly()
{
System.out.println("飞");
}
}
//企鹅
class Penguin extends Bird
{
//子类覆盖父类中的方法
public void fly()
{
System.out.println("飞不了");
}
}
多态存在的三个必要条件
1.要有继承;
2.要有重写;
3.父类引用指向子类对象。
多态的好处:
1.可替换性(substitutability)。
多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility)。
多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。
多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。
它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。
多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
我们用一个例子来描述多态:
比如一个动物类,他有猫和狗两种,猫吃鱼,狗吃肉.
public class AnimalDemo {
public static void main(String[] args) {
//引出多态
Animal a = new Dog();
a.eat();
a = new Cat();
a.eat();
}
}
class Animal{
public void eat(){
System.out.println("吃一般的食物");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("吃鱼");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("吃肉");
}
}
为什么得需要使用final修饰符:
继承关系最大弊端是破坏封装:子类能访问父类的实现细节,而且可以通过方法覆盖的形式修改实现细节.
final本身的含义是“最终的,不可改变的”,它可以修饰非抽象类,非抽象方法和变量。注意:构造方法不能使用final修饰,因为构造方法不能被继承,肯定是最终的。
final修饰的类: 表示最终的类, 该类不能再有子类.
只要满足以下条件就可以把一个类设计成final类:
1.某类不是专门为继承而设计。
2.出于安全考虑,类的实现细节不许改动.
3.确信该类不会再被拓展。
final修饰的变量: 最终的变量,常量,该变量只能赋值一次,不能再赋值.
final是唯一可以修饰局部变量的修饰符.
class SuperClass{
public final void doWork(){}
}
class SubClass extends SuperClass{
//public void doWork(){}//错误: SubClass中的doWork()无法覆盖SuperClass中的doWork()
}
class FinalDemo
{
public static void main(String[] args)
{
final String name = "小明";
//name = "小丽";//错误: 无法为最终变量name分配值
System.out.println(name);
}
}