今日内容:
一.类与类,类与接口,接口与接口
类与类只支持单继承和多层继承
class Demo{}
class Demo1 extends Demo{}
class Demo2 extends Demo1{}
类与接口:一个类继承另一个类的同时可以实现多个接口
//接口1
interface Inter1{
public abstract void show() ;
}
//接口2
interface Inter2{
public abstract void method();
}
//父类
class Father {
public void function(){
System.out.println("function Father");
}
}
//子类
class Son extends Father implements Inter1,Inter2{
@Override
public void show() {
System.out.println("son Show");
}
@Override
public void method() {
System.out.println("son Method");
}
}
//子实现类
class InterImpl implements Inter3{
@Override
public void show() {
}
@Override
public void method() {
}
@Override
public void show2() {
}
}
接口与接口:继承---支持多继承
interface Inter3 extends Inter1,Inter2{
void show2();
}
//父类
class Father {
public void function(){
System.out.println("function Father");
}
}
//子类
class Son extends Father implements Inter1,Inter2{
@Override
public void show() {
System.out.println("son Show");
}
@Override
public void method() {
System.out.println("son Method");
}
}
//子实现类
class InterImpl implements Inter3{
@Override
public void show() {
}
@Override
public void method() {
}
@Override
public void show2() {
}
}
//测试类
public class InterfaceDemo {
public static void main(String[] args) {
//创建具体的子类对象
Son s = new Son() ;
s.show() ;
s.method();
s.function();
}
}
面试题:抽象类与接口的区别
1)成员的区别
抽象类:
成员变量:既可以是常量,也可以变量
成员方法:既可以是抽象方法,也可以是非抽象方法
构造方法:无参/有参构造都存在,子类父类继承,需要分层初始化
接口
成员变量:只能是常量 public static final(默认修饰符)
成员方法:只能是抽象方法 public abstract(默认修饰符)
构造方法:没有---需要借助子实现类进行实例化(创建对象)
2)关系的区别
类与类:可能是一些抽象类, 继承关系,只支持单继承,不支持多继承,但是可以多层继承
abstract class Animal{}
abstract class Cat extends Animal{}
class XXCat extends Cat{}
类与接口:实现关系 implements
一个类继承另一个类(可能也是抽象类)的同时,还可以实现多个接口
接口与接口:继承关系 extends
支持单继承,可以多继承,多层继承!
3)设计理念的区别
抽象类--不能实例化
需要通过具体的子类实现类(继承关系)
核心设计理念体现都是一种"is a"的关系(xxx是XX的一种)
接口---不能实例化
需要通过具体的子实现类进行实例化(实现关系implements)
核心设计理念体现的是 事物的一种额外功能
看成一种"like a"的关系
二.形式参数和返回值(引用类型)
1.形式参数(参数为具体类,抽象类,接口)
具体类
class Test{ public static void main(String[] args) { //第一种输出方式 Student s=new Student();//实例化对象 s.study(); System.out.println("-------------------------"); //第二种输出方式,创建method类对象调用本类方法,并在方法形参赋形参类对象地址值 method s1=new method (); s1.show(s);//相当于new method().show(new Student()); System.out.println("---------------------"); //第三种输出方式 new method().show(new Student()); }} //定义一个类 class Student{ public void study(){ System.out.println("学习快乐"); } } //传参的类 class method{ public void show(Student s){//相当于创建Student类对象,实际参数需要Student类的实例化具体对象 s.study();//方法体,Student类调用自己的方法,局部引用类型变量需要具体的实例化对象 } }
运行结果:
抽象类抽象类不能实例化,实际参数传递该抽象类的子类对象 (抽象类多态)
class Test{ public static void main(String[] args) { //第一种输出方式,实际参数传递该抽象类的子类对象 (抽象类多态) // A a=new B(); // C c=new C(); // c.b(a); // 串联写 new C().b(new B()); System.out.println("-----------------"); //第二种输出方式,直接创建子类对象调用方法 B b=new B(); b.a(); } } abstract class A{ public abstract void a(); } class B extends A{ @Override public void a() { System.out.println("方法a"); } } //定义一个新类演示形参为抽象类 class C{ public void b(A a){ a.a(); } }
输出结果:
接口接口不能实例化,实际参数需要传递该接口的子实现类对象(接口多态)
class Test{ public static void main(String[] args) { //第一种输出方式,接口不能实例化,实际参数需要传递该接口的子实现类对象(接口多态) C c=new C(); A a=new B(); c.show(a); //串联写 // new C().show(new B()); System.out.println("------------------"); //第二种输出方式,接口多态 A a1=new B(); a1.a(); } } //定义一个接口 interface A{ public abstract void a(); } class B implements A { @Override public void a() { System.out.println("B居然还能干这个"); } } //定义一个类演示形式参数为接口的方法 class C{ public void show (A a){ a.a(); } }
2.返回值为(具体类,抽象类,接口)
具体类: 需要返回的是当前具体类的对象 !
class Test{
public static void main(String[] args) {
B b=new B();
A a=b.b();//创建B类对象相当于new A();返回值给到B类对象,B类对象的地址值给了A类对象
a.a();
}
}
class A{
public void a(){
System.out.println("show a");
}
}
class B{
public A b(){
return new A();
}
}
返回抽象类需要返回的是当前抽象类的子类对象(抽象类多态)
class Test{ public static void main(String[] args) { C c=new C();//返回值到C类对象 A a=c.c();//相当于new B(); a.a(); } } abstract class A{ abstract void a(); } class B extends A{ @Override void a() { System.out.println("返回抽象类"); } } //定义一个类演示返回值为抽象类 class C{ public A c(){ return new B(); } }
返回接口需要返回的是当前接口的子类对象(接口多态)
三.包package
不同包下的无关类中
四.权限修饰符public protected private
关于权限修饰符的应用范围
在同一个包下 的同一个类中 | 在同一个包下的子类中/在同一个包下的无关类中 | 在不同包下的子类中 | 不同包的无关类中 | |
private | Y | |||
默认修饰符 | Y | Y | ||
public | Y | Y | Y | Y |
protected | Y | Y | Y |
* 私有的修饰符private:权限最小 (开发中,也就是定义实体类(描述现实世界事物),属性私有化!)
* public权限最大
* protectd:一般源码中见到(二阶段去前后端交互的时候 Apache开源机构 Servlet--->一些业务都是protected)
五.内部类
一个类A中,有一个类B,将类B就称为类A的内部类,类A就是类B的外部类!
内部类有两种格式
1)成员内部类---->在一个外部类的成员位置(类中,方法外)定义的类
2)局部内部类---->在外部类的局部位置(方法定义中)定义的类
成员内部类可以访问外部类的成员,包括私有相关的!
如何直接通过外部类去访问内部类的成员呢?(格式 重点)
外部类.内部类名 对象名 = new 外部类名().new 内部类名();
类名.内部类成员;
//外部类
class A{
//成员内部类
class B{}
public void a(){
//局部内部类
class C{}
}
外部类如何访问静态成员内部类的成员
格式:外部类名.内部类名 对象名=new 外部类名.内部类();
对象名.静态成员内部类成员;
如果静态内部类的成员方法也是静态的
外部类名.内部类名.静态成员方法名();
静态内部类里的成员方法/变量无论是静态还是非静态的访问外部类的成员也必须是静态的
六.常用类(凡是类型转换的都是重点)
object
String
StringBuffer(线程安全类)
java.util.Date(日期类)