目录
1.static静态变量
2.静态方法和工具类
3.static注意事项
4.继承
5.多态
6.包
7.final关键字
8.权限修饰符
9.代码块
10.抽象类和抽象方法
11.接口
12.内部类
被static修饰的成员变量,叫做静态变量。
特点:被该类所有对象共享;
不属于对象,属于类;
随着类的产生而存在,优先于对象存在;
调用方式:类名调用(推荐);对象名调用。
e.g:
package csdn;
public class Student {
String name;
static String teacher_name;//一个班的学生,共享一个老师
Student(String name){
this.name=name;
}
public void show_info(){
System.out.print("学生:"+name+" ");
System.out.println("老师:"+teacher_name);
}
}
In a word:当一个类的对象需要共享一个成员变量时,可以使用static修饰该变量,使之成为静态变量,供所有对象共享。
特点:多用在测试类和工具类,JavaBean很少用到。
调用方式:类名调用(推荐);对象名调用。
PS:工具类是用来帮助做一些事情的类,在这类需要私有化构造方法(外界创建工具类的对象没有意义),方法定义为静态。
e.g:创建数组工具类,加以测试;
package csdn;
public class ArrayUtil {
//私有化构造方法
private ArrayUtil(){
}
//打印工具
public static String PrintArray(int arr[]){
StringBuilder sb=new StringBuilder();
sb.append("[");
for(int i=0;i
package csdn;
public class ArrayUtilTest {
public static void main(String[] args) {
//方法类无法外界创建对象,直接使用类名调用成员方法。
int arr[]={1,2,3,4,5};
System.out.println(ArrayUtil.PrintArray(arr));//[1,2,3,4,5]
System.out.println(ArrayUtil.PrintAverage(arr));//3
}
}
○静态方法只能访问静态变量和静态方法;
○静态方法中没有this关键字。
①.关键字extends,可以让一个类和另一个类建立起继承关系。
e.g:
public class Student extends Person{}
Student称子类(派生类),Person称父类(基类)
好处:子类中重复的代码可以提取到父类中,提高代码复用性;
子类可以在父类的基础上增加功能。
package csdn;
public class Person {
private String name;
private int age;
}
class Student extends Person{
public void Study(){
System.out.println("学生学习");
}
}
class Teacher extends Person{
public void Teach(){
System.out.println("老师授课");
}
}
②.继承的特点
Java只支持单继承(一个子类只继承一个父类),不支持多继承,但支持多层继承
(子类A可以继承父类B,父类B可以继承父类C)。
每个类都直接或间接继承于Object(虚拟机自动)。
public class A{}
//其实是
public class A extends Object{}
子类能访问父类的哪些内容:
构造方法 | 非私有 不可继承 | 私有 不可继承 |
成员变量 | 非私有 可继承 | 私有 可继承 |
成员方法 | 非私有 可继承 | 私有 不可继承 |
③.继承中成员变量的访问特点
就近原则,xxx从局部位置开始找,到本类成员位置找,最后到父类成员位置找。
this.xxx从本类成员位置开始找,到父类成员位置找。
super.xxx直接到父类成员位置找。
public class Test {
public static void main(String[] args) {
Er e=new Er();
e.Print();
}
}
class Die{
String name="爹";
}
class Er extends Die{
String name="儿子";
public void Print(){
String name="儿中儿";
System.out.println(name);//儿中儿
System.out.println(this.name);//儿子
System.out.println(super.name);//爹
}
}
④.继承中成员方法的访问特点
方法重写:当父类中的方法不满足子类的要求,就需要重写方法;@Override放在重写方法上面,校验子类重写方法语法;
public class Test02 {
public static void main(String[] args) {
exchangeStudents es=new exchangeStudents();
es.show_me();
}
}
class Students{
public void eat(){
System.out.println("吃河道果实");
}
public void drink() {
System.out.println("喝腐败药水");
}
}
class exchangeStudents extends Students{
public void show_me(){
this.eat();//吃探照果实
this.drink();//喝复用型药水
super.eat();//吃河道果实
super.drink();//喝腐败药水
}
@Override
public void eat(){
System.out.println("吃探照果实");
}
public void drink(){
System.out.println("喝复用型药水");
}
}
方法重写注意事项:
重写的方法名,形参列表要和父类一样;
重写的方法访问权限子类必须大于等于父类(不设权限 重写方法的返回值子类必须小于等于父类; 私有方法不能重写; 静态方法不能重写; (未添加到虚方法表的方法不能重写); (重写的本质:覆盖虚方法表中的方法)。 ⑤.继承中构造方法的访问特点 父类的构造方法不会被子类继承;子类的所有构造方法默认先访问父类的无参构造,再执行自己。 子类的构造方法第一句默认super();不写也存在且必须在第一行。 子类想调用父类的有参构造时必须加super。 e.g: ①.多态就是对象的多种形态 前提:有继承关系/实现关系 有父类引用指向子类对象 有方法的重写 好处:使用父类对象为参数,可以接收所有子类对象。 ②. 调用成员变量时:编译看左边(父类),运行看左边(子类); 调用成员方法时:编译看左边,运行看右边; ③多态的优势和缺陷 优势:定义方法时,使用父类作参数,可以接收所有子类,便利; 在多态形式下,子类可以实现解耦合,便于维护。 弊端:不能使用子类独有的功能。 解决方案:转换成子类类型,从而调用子类独有的功能。 PS:instanceof关键字 a instance typeB:判断a是否为B类型,是返回true否返回false。 有时为了避免类型转换出错,会使用instanceof先判断再进行强转。 包就是文件夹,用来管理不同功能的Java类。 导包规则: 使用同一包中的类,不需要导包; 使用java.lang包中的类(如String),不需要导包; 使用两个包中的同名类,需要使用全类名。 修饰方法时:表示不能被重写; 修饰类时:表示不能被继承; 修饰变量时:表示常量,只能被赋值一次。 常量命名规范:单个单词:全部大写;多个单词:全部大写,用下划线隔开。 细节:final修饰基本数据类型(如:int),表示数据值不能改变; final修饰引用数据类型(如:数组),表示数据地址值不能改变,但存储的数值可以改变。 实际开发中使用频繁的是private和public ①局部代码块 是为了节省内存,提前结束变量生命周期。 现在已经用不到,计算机内存不需要节省那么点空间。 ②构造代码块 写在成员位置,把多个构造方法重复的代码提取出来,优先于构造方法执行。 这种方法现在也不常用,因为不灵活,构造代码块必定执行,且优先于构造方法执行。 更常用将多个构造方法中的重复代码提取成一个方法。 ③静态代码块 static{} 特点:随着类的加载而执行,且只执行一次。用于加载类时的初始化。 将共性的方法抽取到父类后,如果不能确定具体的方法体,就可以定义为抽象方法; 如果一个类中存在抽象方法,这个类必须声明为抽象类。 定义格式: 抽象方法:public abstract 返回值类型 方法名(参数列表); 抽象类:public abstract class 类名{} 注意事项:Ⅰ抽象类不能实例化(创造对象); Ⅱ抽象类中不一定有抽象方法,有抽象方法的一定是抽象类; Ⅲ可以有构造方法; Ⅳ抽象类的子类要么重写抽象类所有抽象方法,要么该子类也是抽象类。 ①接口就是一种对行为的抽象。 接口用关键字interface定义 接口不能实例化 接口和类之间是实现关系,用关键字implements实现 接口的子类(实现类)要么重写接口的所有抽象方法,要么该子类是抽象类 接口的子类可以多实现 还可以在继承父类的同时实现多个接口 e.g:创建Person类,子类为中国人,外国人,假人; 因为假人没有Speak行为,故Speak行为需写成接口,供中国人和外国人调用。 ②接口中成员特点 成员变量只能是常量,默认 public static final 没有构造方法 成员方法只能是抽象方法,默认public abstract ③JDK8接口中新增的方法 JDK7之前接口中只能写抽象方法; JDK8可以定义有方法体的方法; JDK9可以定义私有方法。 默认方法:public default 返回值类型 方法名(){} 注意:默认方法不是抽象类,不强制重写。如果要重写,重写时去掉default; public可以省略,default不能省略; 静态方法:public static 返回值类型 方法名(){} 注意:静态方法只能用接口名调用; public可以省略,static不能省略。 ④接口应用: 接口代表规则,是行为的抽象。想让哪个类拥有这个行为,就让这个类实现对应的接口; 当一个方法的参数是接口,可以传递所有接口的实现类,这种方式称为接口的多态。 ⑤适配器设计模式 当一个接口中抽象方法过多,而我们只需要用到一部分,就可以使用适配器设计模式; 书写步骤: 编写中间类XXXAdapter实现对应接口,对接口中的抽象方法全部进行空实现,让真正的实现类继承中间类,重写需要的方法,为了避免其他类创造中间类的对象,中间适配器类需要用abstract修饰。 ①内部类表示的事物是外部类的一部分,内部类单独出现没有意义。 内部类可以直接访问外部类的成员,包括private修饰的; 外部类不能直接访问内部类的成员,如果想访问,必须创建对象。 e.g:引擎和汽车的关系 ②内部类的分类 成员内部类:写在成员位置,属于外部类的成员 获取内部类成员的方法: Ⅰ.在外部类编写对外提供内部类成员的方法 Ⅱ.外部类名.内部类名 对象名 = new 外部类名().new 内部类名(); 外部类成员变量和内部类成员变量重名时,怎么在内部类访问 局部内部类 将内部类定义在方法里就叫局部内部类。 外部无法直接使用,要在方法内创建对象方可使用 局部内部类可以直接访问外部类的成员,也可访问方法内的局部变量 静态内部类 当成员内部类用static修饰时,就叫静态内部类,静态内部类只能访问外部类的静态成员变量和静态成员方法,如果想访问非静态的需要创建对象。 创建静态内部类对象:外部类名.内部类名 对象名=new 外部类名.内部类名(); 调用静态方法:外部类名.内部类名.方法名(); 匿名内部类 匿名内部类本质就是隐藏了类名的内部类 格式:new 类名/接口名(){ 重写方法; }; 绿色的部分其实才是匿名内部类,加上new 类名/接口名后他的本质应该是一个对象,和类名/接口名的关系应该是继承/实现。 e.g:直接将匿名内部类作为对象传给方法。 In a word,匿名内部类整体是一个类的对象或者一个接口的实现类对象。 使用场景: 当方法的参数是类/接口时,可以传递这个类的子类对象/实现类对象,如果只需要执行一次,就可以使用匿名内部类简化代码。public class Test {
public static void main(String[] args) {
Students s=new Students("王德发",19);
s.Print();
}
}
class Person {
String name;
int age;
public Person(){
System.out.println("父类的无参构造");
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
}
class Students extends Person{
public Students(){
super();
System.out.println("子类的无参构造");
}
public Students(String name,int age){
super(name,age);
}
public void Print(){
System.out.println(this.name);
System.out.println(this.age);
}
}
5.多态
public class Test {
public static void main(String[] args) {
Student s=new Student();
s.setName("王德发");
s.setAge(19);
Teacher t=new Teacher();
t.setName("墨菲特");
t.setAge(20);
show(s);//学生叫:王德发年龄19
show(t);//老师叫:墨菲特年龄20
}
//父类对象作参数
public static void show(Person p){
p.Print();
}
}
class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
public void Print(){
System.out.println(this.name+" "+this.age);
}
}
class Student extends Person{
@Override
public void Print(){
System.out.println("学生叫:"+this.name+"年龄"+this.age);
}
}
class Teacher extends Person{
@Override
public void Print(){
System.out.println("老师叫:"+this.name+"年龄"+this.age);
}
}
public class Test {
public static void main(String[] args) {
//左 右
Animal a=new Dog();
//调用成员变量,javac编译时看左边,如果左边(父类)有该变量,编译成功,反之编译失败
//javac运行时看左边,实际获取的就是父类中该成员变量的值。
System.out.println(a.name);//动物
//调用成员方法,javac编译时看左边,如果左边(父类)有该方法,编译成功,反之编译失败
//javac运行时看右边,实际获取的是子类中的成员方法
a.Print();//这是个狗
}
}
class Animal{
String name="动物";
public void Print(){
System.out.println("这是个动物");
}
}
class Dog extends Animal{
String name="狗";
@Override
public void Print(){
System.out.println("这是个狗");
}
}
public class Test {
public static void main(String[] args) {
Animal a=new Dog();
//a.EatRou();报错
//原因:多态情况下调用成员方法,从左边找,父类中未定义Eat函数,故javac编译报错
//解决:类型转换:
Dog d = (Dog)a;
d.EatRou();
}
}
class Animal{
public void Print(){
System.out.println("动物吃饭");
}
}
class Dog extends Animal{
public void EatRou(){
System.out.println("狗吃小肉干");
}
}
class Cat extends Animal{
public void EatYu(){
System.out.println("猫吃小鱼干");
}
}
6.包
7.final关键字
8.权限修饰符
范围:private<默认
同一类中
同一个包中其他类
不同包下的子类
不同包下的无关类
private
√
默认
√
√
protected
√
√
√
public
√
√
√
√
9.代码块
public class Code {
public static void main(String[] args) {
{
int a=10;
}//在这里a已经从内存中消失
System.out.println(a);//a的生命周期已结束,无法访问
}
}
public class Code {
public static void main(String[] args) {
Students s=new Students();
//这是构造代码块
//空参构造
Students s_1=new Students("王德发",19);
//这是构造代码块
//有参构造
}
}
class Students{
String name;
int age;
{
System.out.println("这是构造代码块");
}
public Students() {
System.out.println("空参构造");
}
public Students(String name, int age) {
System.out.println("有参构造");
this.name = name;
this.age = age;
}
}
public class Code {
public static void main(String[] args) {
Students s=new Students();
//这是构造代码块
//空参构造
Students s_1=new Students("王德发",19);
//有参构造
}
}
class Students{
String name;
int age;
static {
System.out.println("这是构造代码块");
}
public Students() {
System.out.println("空参构造");
}
public Students(String name, int age) {
System.out.println("有参构造");
this.name = name;
this.age = age;
}
}
10.抽象类和抽象方法
public abstract class Abstract {
public abstract void Work();
}
abstract class Animals{
public void Print(){
System.out.println("动物");
}
}
11.接口
public interface 接口名{}
public class 类名 implements 接口名{}
public class 类名 implements 接口1,接口2{}
public class 子类名 extends 父类名 implements 接口1,接口2{}
public class Test {
public static void main(String[] args) {
Chinese c=new Chinese("王德发",19);
System.out.println("名字:"+c.getName()+"年龄:"+c.getAge());
c.speak();
c.food();
dummy d=new dummy("目标假人",190);
System.out.println("名字:"+d.getName()+"年龄:"+d.getAge());
d.food();
}
}
abstract class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
public abstract void food();
}
interface Speak {
public abstract void speak();
}
class Chinese extends Person implements Speak{
public Chinese() {
}
public Chinese(String name,int age) {
super(name,age);
}
@Override
public void food() {
System.out.println("吃饺子");
}
@Override
public void speak() {
System.out.println("讲汉语");
}
}
class foreigners extends Person implements Speak{
public foreigners(){
}
public foreigners(String name,int age){
super(name,age);
}
@Override
public void food() {
System.out.println("吃比萨");
}
@Override
public void speak() {
System.out.println("讲外语");
}
}
class dummy extends Person{
public dummy(){
}
public dummy(String name,int age){
super(name,age);
}
@Override
public void food() {
System.out.println("吃伤害");
}
//假人没有Speak行为
}
12.内部类
public class Car {
String name;
int age;
String brand;
public void show(Car this){
System.out.println("车辆年限:"+this.age);
Engine e=new Engine();//外部类想访问内部类成员,需要创建对象
System.out.println("引擎寿命:"+e.engineage);
}
class Engine{
String enginename;
int engineage;
public void show(){
System.out.println("车辆品牌:"+brand);
System.out.println("引擎型号:"+enginename);
}
}
}
public class Test {
public static void main(String[] args) {
Outer.Iner oi=new Outer().new Iner();
oi.show();//10
}
}
class Outer{
int a=10;
class Iner{
public void show(){
System.out.println(a);
}
}
}
class Outer{
private int a=10;
class Iner{
private int a=20;
public void show(){
int a=30;
System.out.println(a);//30
System.out.println(this.a);//20
System.out.println(Outer.this.a);//10
}
}
}
public class Test {
public static void main(String[] args) {
Outer.Iner oi=new Outer.Iner();
oi.show1();//静态内部类的非静态方法
Outer.Iner.show2();//静态内部类的静态方法
}
}
class Outer{
static class Iner{
public void show1(){
System.out.println("静态内部类的非静态方法");
}
public static void show2(){
System.out.println("静态内部类的静态方法");
}
}
}
public class Test {
public static void main(String[] args) {
show(
new Animal(){
@Override
public void eat(){
System.out.println("狗吃骨头");
}
}
);//狗吃骨头
}
public static void show(Animal a){
a.eat();
}
}
abstract class Animal{
public abstract void eat();
}