06 面向对象:多态&抽象类&接口&权限修饰符&内部类
多态:
/*
多态(polymorphic)概述
* 事物存在的多种形态
多态前提
* a:要有继承关系。
* b:要有方法重写。
* c:要有父类引用指向子类对象。
* 成员变量
* 编译看左边(父类),运行看左边(父类)。
* 成员方法
* 编译看左边(父类),运行看右边(子类)。动态绑定
* 静态方法
* 编译看左边(父类),运行看左边(父类)。
* (静态和类相关,算不上重写,所以,访问还是左边的)
* 只有非静态的成员方法,编译看左边,运行看右边 */
class Demo_Polymorphic {
public static void main(String[] args)
{
Animal a = new Cat(); // 父类引用指向子类对象
a.eat(); // 猫吃鱼 // 如果父类没有eat方法就会报错,编译看左边(父类)
System.out.println(a.num); // 10 成员变量,运行看父类
a.method(); // Animal static method ,相当于Animal.method()
}
}
class Animal
{
int num = 10;
public void eat(){
System.out.println("动物吃饭");
}
public static void method(){
System.out.println("Animal static method");
}
}
class Cat extends Animal
{
int num = 20;
public void eat(){
System.out.println("猫吃鱼");
}
public static void method(){
System.out.println("Cat static method");
}
}
/*
* A:多态的好处
* a:提高了代码的维护性(继承保证)
* b:提高了代码的扩展性(由多态保证)
* B:可以当作形式参数,可以接收任意子类对象
* C:多态的弊端
* 不能使用子类的特有属性和行为。
*/
class Demo_Polymorphic1 {
public static void main(String[] args)
{
Animal a = new Cat();// 向上转型
a.eat();
Cat c = (Cat)a; //向下转型
c.method(); // Animal a2 = new Dog();
methods(new Dog());
}
public static void methods(Animal a){ // 作形式参数
if (a instanceof Cat)
{
Cat c = (Cat)a;
c.method();
}
else if (a instanceof Dog)
{
Dog d = (Dog)a;
d.method();
}else{
a.eat();
}
}
}
class Animal
{
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal
{
public void eat(){
System.out.println("猫吃鱼");
}
public void method(){
System.out.println("猫捉老鼠");
} }
class Dog extends Animal
{
public void eat(){
System.out.println("狗吃肉");
}
public void method(){
System.out.println("狗看门");
}
}
多态的好坏
抽象的特点:
/*
抽象类特点
* a:抽象类和抽象方法必须用abstract关键字修饰
* abstract class 类名 {}
* public abstract void eat();
* b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
* c:抽象类不能实例化那么,抽象类如何实例化呢?
* 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
* d:抽象类的子类
* 要么是抽象类
* 要么重写抽象类中的所有抽象方法
*
* 抽象类特点B:抽象类特点
* a:抽象类和抽象方法必须用abstract关键字修饰
* abstract class 类名 {}
* public abstract void eat();
* b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
* c:抽象类不能实例化那么,抽象类如何实例化呢?
* 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
* d:抽象类的子类
* 要么是抽象类
* 要么重写抽象类中的所有抽象方法
*/
class Demo_Abstract {
public static void main(String[] args)
{
// Animal a = new Animal();//错误: Animal是抽象的; 无法实例化
new Cat().method();
}
}
abstract class Animal
{
public abstract void method();
public void eat(){
System.out.println("eat");
}
}
class Cat extends Animal
{
public void method(){
System.out.println("捉老鼠");
}
}
抽象类的成员特点:
* 抽象类的成员特点
* a:成员变量:既可以是变量,也可以是常量。abstract是否可以修饰成员变量?不能修饰成员
变量
* b:构造方法:有。
* 用于子类访问父类数据的初始化。
* c:成员方法:既可以是抽象的,也可以是非抽象的。
* 抽象类的成员方法特性:
* a:抽象方法 强制要求子类做的事情。
* b:非抽象方法 子类继承的事情,提高代码复用性。
一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
* 可以
* 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成
abstract不能和哪些关键字共存
abstract和static
被abstract修饰的方法没有方法体
被static修饰的可以用类名.调用,但是类名.调用抽象方法是没有意义的
abstract和final
被abstract修饰的方法强制子类重写
被final修饰的不让子类重写,所以他俩是矛盾
abstract和private
被abstract修饰的是为了让子类看到并强制重写
被private修饰不让子类访问,所以他俩是矛盾的
abstract class Demo {
//public static abstract void print(); //错误: 非法的修饰符组合: abstract 和static
//public final abstract void print(); //错误: 非法的修饰符组合: abstract 和final
private abstract void print(); //错误: 非法的修饰符组合: abstract和private
}
接口:
/*
* A:接口概述
* 从狭义的角度讲就是指java中的interface
* 从广义的角度讲对外提供规则的都是接口
* B:接口特点
* a:接口用关键字interface表示
* interface 接口名 {}
* b:类实现接口用implements表示
* class 类名 implements 接口名 {}
* c:接口不能实例化
* 按照多态的方式来实例化。
* d:接口的子类
* a:可以是抽象类。但是意义不大。
* b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
*/
class Demo_Interface {
public static void main(String[] args)
{
// Inter i = new Inter();//错误: Inter是抽象的; 无法实例化
Inter i = new A(); // 按照多态的方式实例化
i.print(); new Y().print();
}
}
interface Inter
{
public abstract void print(); // 接口中的方法都是抽象的
}
class A implements Inter
{
public void print(){
System.out.println("a");
}
}
/*
接口成员特点
* 成员变量;只能是常量,并且是静态的并公共的。
* 默认修饰符:public static final
* 建议:自己手动给出。
* 构造方法:接口没有构造方法。
* 成员方法:只能是抽象方法。
* 默认修饰符:public abstract
* 建议:自己手动给出。
*/
interface X
{
public static final int num = 10;
public abstract void print(); // public X(){}//接口没有构造方法 // public void print(){} // 只能是抽象方法 }
class Y implements X
{
public Y(){
super(); // 父类object
}
public void print(){
System.out.println(num);
} } class Demo3_Interface {
public static void main(String[] args) {
System.out.println("Hello World!");
}
} /*
* 类与类,类与接口,接口与接口的关系
* a:类与类:
* 继承关系,只能单继承,可以多层继承。
* b:类与接口:
* 实现关系,可以单实现,也可以多实现。
* 并且还可以在继承一个类的同时实现多个接口。
* c:接口与接口:
* 继承关系,可以单继承,也可以多继承。
*/ interface InterA {
public abstract void printA();
} interface InterB {
public abstract void printB();
} interface InterC extends InterB,InterA {
}
//class Demo implements InterA,implements InterB { //这么做不允许是非法的
class Demo extends Object implements InterA,InterB {
public void printA() {
System.out.println("printA");
} public void printB() {
System.out.println("printB");
}
}
class Demo3_Interface {
public static void main(String[] args) {
System.out.println("Hello World!");
}
} /*
* A:类与类,类与接口,接口与接口的关系
* a:类与类:
* 继承关系,只能单继承,可以多层继承。
* b:类与接口:
* 实现关系,可以单实现,也可以多实现。
* 并且还可以在继承一个类的同时实现多个接口。
* c:接口与接口:
* 继承关系,可以单继承,也可以多继承。
*/ interface InterA {
public abstract void printA();
} interface InterB {
public abstract void printB();
} interface InterC extends InterB,InterA {
}
//class Demo implements InterA,implements InterB { //这么做不允许是非法的
class Demo extends Object implements InterA,InterB {
public void printA() {
System.out.println("printA");
} public void printB() {
System.out.println("printB");
}
} class Demo3_Interface {
public static void main(String[] args) {
System.out.println("Hello World!");
}
} /*
* A:类与类,类与接口,接口与接口的关系
* a:类与类:
* 继承关系,只能单继承,可以多层继承。
* b:类与接口:
* 实现关系,可以单实现,也可以多实现。
* 并且还可以在继承一个类的同时实现多个接口。
* c:接口与接口:
* 继承关系,可以单继承,也可以多继承。
*/ interface InterA {
public abstract void printA();
} interface InterB {
public abstract void printB();
} interface InterC extends InterB,InterA {
}
//class Demo implements InterA,implements InterB { //这么做不允许是非法的
class Demo extends Object implements InterA,InterB {
public void printA() {
System.out.println("printA");
} public void printB() {
System.out.println("printB");
}
} class Demo3_Interface {
public static void main(String[] args) {
System.out.println("Hello World!");
}
} /*
* A:类与类,类与接口,接口与接口的关系
* a:类与类:
* 继承关系,只能单继承,可以多层继承。
* b:类与接口:
* 实现关系,可以单实现,也可以多实现。
* 并且还可以在继承一个类的同时实现多个接口。
* c:接口与接口:
* 继承关系,可以单继承,也可以多继承。
*/ interface InterA {
public abstract void printA();
} interface InterB {
public abstract void printB();
} interface InterC extends InterB,InterA {
}
//class Demo implements InterA,implements InterB { //这么做不允许是非法的
class Demo extends Object implements InterA,InterB {
public void printA() {
System.out.println("printA");
} public void printB() {
System.out.println("printB");
}
}
抽象类和接口的区别
* 成员区别
* 抽象类:
* 成员变量:可以变量,也可以常量
* 构造方法:有
* 成员方法:可以抽象,也可以非抽象
* 接口:
* 成员变量:只可以常量
* 成员方法:只可以抽象 * 关系区别
* 类与类
* 继承,单继承
* 类与接口
* 实现,单实现,多实现
* 接口与接口
* 继承,单继承,多继承 * 设计理念区别
* 抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
* 接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。
为什么要有包:
* 将字节码(.class)进行分类存放
* 包其实就是文件夹
包的定义及注意事项
* A:定义包的格式
* package 包名;
* 多级包用.分开即可
* B:定义包的注意事项
* A:package语句必须是程序的第一条可执行的代码
* B:package语句在一个java文件中只能有一个
* C:如果没有package,默认表示无包名
如何编译运行带包的类:
* a:javac编译的时候带上-d即可
* javac -d . HelloWorld.java
* b:通过java命令执行。
* java 包名.HellWord
import关键字的概述和使用:
* 为什么要有import
* 其实就是让有包的类对调用者可见,不用写全类名了
* 导包格式
* import 包名;
* 注意:
这种方式导入是到类的名称。
虽然可以最后写*,但是不建议。
四种权限修饰符:
本类 | 同一个包下(子类和无关类) | 不同包下(子类) | 不同包下(无关类) | |
private | Y | |||
默认 | Y | Y | ||
protected | Y | Y | Y | |
public | Y | Y | Y | Y |
类及其组成所使用的常见修饰符:
* A:修饰符:
* 权限修饰符:private,默认的,protected,public
* 状态修饰符:static,final
* 抽象修饰符:abstract
* B:类:
* 权限修饰符:默认修饰符,public
* 状态修饰符:final
* 抽象修饰符:abstract * 用的最多的就是:public * C:成员变量:
* 权限修饰符:private,默认的,protected,public
* 状态修饰符:static,final * 用的最多的就是:private * D:构造方法:
* 权限修饰符:private,默认的,protected,public * 用的最多的就是:public * E:成员方法:
* 权限修饰符:private,默认的,protected,public
* 状态修饰符:static,final
* 抽象修饰符:abstract * 用的最多的就是:public * F:除此以外的组合规则:
* 成员变量:public static final 接口
* 成员方法:
* public static
* public abstract
* public final
内部类访问特点
* a:内部类可以直接访问外部类的成员,包括私有。
* b:外部类要访问内部类的成员,必须创建对象。
* 外部类名.内部类名 对象名 = 外部类对象.内部类对象; class Demo_Inner {
public static void main(String[] args)
{
Outer.Inner oi = new Outer().new Inner();
oi.method();
// 访问内部类的私有使用
Outer2 o = new Outer2();
o.print();
// 访问静态成员内部类
Outer3.Inner o3 = new Outer3.Inner();
o3.method(); Outer4.Inner.method();
}
}
class Outer
{
private int num = 10;
class Inner
{
public void method(){
System.out.println(num);
}
}
}
// 内部类的私有使用
class Outer2
{
private int num = 10;
private class Inner
{
public void method(){
System.out.println(num);
}
}
public void print(){
new Inner().method();
}
}
/*
静态成员内部类
* 成员内部类被静态修饰后的访问方式是:
* 外部类名.内部类名 对象名 = 外部类名.内部类对象;
*/
class Outer3
{
static class Inner
{
public void method(){
System.out.println("static");
}
}
}
class Outer4
{
static class Inner
{
public static void method(){
System.out.println("static");
}
}
}
使用已知的变量,在控制台输出30,20,10。
// 内部类之所以能获得外部类的成员,是因为他能获取到外部类的引用 外部类名.this
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
} class Demo_InnerClass {
public static void main(String[] args)
{
Outer o = new Outer();
o.method();
}
}
// 局部内部类
class Outer
{
public void method(){
final int num = 10; // 局部内部类访问局部变量必须用final修饰
class Inner
{
public void print(){
System.out.println(num);
}
}
new Inner().print();
}
/*
public void Test(){
new Inner().print();// 错误,局部内部类,只能在其所在的方法中访问
}
*/
} /*
* 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?
因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周 期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部 变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可 以继续使用 但是jdk1.8,如果在书写代码时候,没有手动添加,系统底层也会默给你final */
匿名内部类:
/*
* A:匿名内部类
* 就是内部类的简化写法。
* B:前提:存在一个类或者接口
* 这里的类可以是具体类也可以是抽象类。
* C:格式:
new 类名或者接口名(){
重写方法;
}
* D:本质是什么呢?
* 是一个继承了该类或者实现了该接口的子类匿名对象。
*/
class Demo_InnerClass2 {
public static void main(String[] args)
{
new Outer().method();
}
}
interface Inner
{
public abstract void print();
}
class Outer
{
public void method(){
new Inner(){
public void print(){
System.out.println("Hello World!");
}
}.print();
}
}
// 匿名内部类重写多个方法调用
// 建议匿名类只针对重写一个方法时候使用
interface Inner2
{
public abstract void print1();
public abstract void print2();
}
class Outer2
{
public void method(){
Inner2 i = new Inner2(){ // 父类引用指向子类对象
public void print1(){
System.out.println("print1");
}
public void print2(){
System.out.println("print1");
}
/*
public void print3(){
System.out.println("print3");
}
*/
};
i.print1();
i.print2();
// i.print3(); // 匿名内部类是不能向下转型的,因为没有自类类名
}
}
class Test_NoNameInnerClass {
public static void main(String[] args)
{
Outer.method().show();
// 相当于
Inter i = Outer.method();
i.show();
}
}
interface Inter
{
void show();
}
class Outer
{
public static Inter method(){
return new Inter(){
public void show(){
System.out.println("Hello World!");
}
};
}
}
/*
Hello World!
*/
重写补充:返回值类型是子父类
/*
重写:子父类出现了一模一样的方法
(注意:返回值类型可以是子父类)
*/
class Demo_FaSonClass {
public static void main(String[] args)
{ }
}
class Person
{
public void print(){
System.out.println("Hello World!");
}
}
class Person2 extends Person
{
public void print(){
System.out.println("Hello World!2");
}
}
class Father
{
public Person method(){
return new Person(); //Person与Person2 是子父类
}
}
class Son extends Father
{
public Person2 method(){
return new Person2(); //Person与Person2 是子父类
}
}
06 面向对象:多态&抽象类&接口&权限修饰符&内部类的更多相关文章
- java面向对象之关键字,权限修饰符
1.关键字:this,static,package,importthis:1.表示对当前对象的引用!2.表示用类的成员变量,而非函数参数,注意在函数参数和成员变量同名是进行区分!其实这是第一种用法的特 ...
- Java 面向对象(八) 权限修饰符 和 final、native 关键字
一.权限修饰符 1.概述 在 Java 中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限: public:公共的: protected:受保护的: default: ...
- this/super/static/final/匿名对象/继承/抽象类/访问权限修饰符
1.this关键字的作用 1)调用本类中的属性; 2)调用本类中的构造方法;且只能放首行,且必须留一个构造方法作为出口,即不能递归调用 3)表示当前对象; 2.匿名对象 ...
- 【Java】基础:常见修饰符(权限修饰符以及abstract、static、final等)与变量的描述
1. 修饰符 public.protected.private.default abstract.static.final. abstract:抽象类.抽象方法 static:静态变量.静态方法.静态 ...
- 面向对象 继承 抽象类 接口 static 权限修饰符
Day01 面向对象 继承 抽象类 接口 static 1.匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. 2.类的继承是指在一个现有类的基础上去构建一个新的类,构建出 ...
- java自学第3期——继承、多态、接口、抽象类、final关键字、权限修饰符、内部类
一.继承: 关键字extends /* 定义一个父类:人类 定义父类格式:public class 父类名称{ } 定义子类格式:public class 子类名称 extends 父类名称{ } * ...
- C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态
C#基础--类/接口/成员修饰符,多态.重载.重写,静态和非静态 类/接口/成员修饰符 C#修饰符---接口: 接口默认访问符是internal接口的成员默认访问修饰符是public C#修饰符--类 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_02-继承与多态_第6节 权限修饰符_6_四种权限修饰符
四种权限修饰符.从大到小 纵向再分成四种情况 同一个类 同一个类里面.private方式,可以访问到本类里面的 num成员变量 前面不写修饰符也能访问到 (default)就是不写的这种情况 受保护的 ...
- 匿名类、包、权限修饰符_DAY10
1:内部类(理解) (1)把类定义在一个类的内部. (2)特点: A:内部类可以直接使用外部类的成员,包括私有. B:外部类要使用内部类成员,必须创建对象使用. 例子: public c ...
随机推荐
- jdk重装后com.sun.tools.javac.Main is not on the classpath的问题 .
在重装了JDk之后,在编译工程的时候出现如下错误: com.sun.tools.javac.Main is not on the classpath.Perhaps JAVA_HOME does no ...
- 网页的MVC模式简介
#! /usr/bin/env python3 # -*- coding:utf-8 -*- #MVC:Model-View-Controller 模型-视图-控制器 #Python处理URL的函数就 ...
- Cracking The Coding Interview 2.2
#include <iostream> #include <string> using namespace std; class linklist { private: cla ...
- C数据结构 : 线性表 与 链表
一.线性表 一般表现为数组,使用一组地址连续的存储单元依次存储数据元素,如图: 它具有如下特点: 长度固定,必须在分配内存之前确定数组的长度. 存储空间连续,即允许元素的随机访问. 存储密度大,内存中 ...
- Bluedroid: 蓝牙协议栈源码剖析
一. 基础知识介绍 1.缩略语 BTIF: Bluetooth Interface BTU : Bluetooth Upper Layer BTM: Bluetooth Manager BTE: Bl ...
- log4net在release模式下无法生成文件或不写入日志
在Debug模式一切正常,但是在release模式下log4net不工作,查了很多资料,终于解决.具体做如下检查修改. 1.检查log4net写入日志文件路径是否正确: 2.检查对应日志文件路径是否有 ...
- 2010年腾讯前端面试题学习(jquery,html,css部分)
看了牛人写的回忆文章,里面有2010年腾讯的前端面试题,里面涉及到不少基础性的问题,js部分已学习,这是jquery,html和css部分,学习一下:) 原文地址:https://segmentfau ...
- Vuejs 用$emit 与 $on 来进行兄弟组件之间的数据传输
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ubantu清理垃圾文件操作
安装的ubuntu 18.01 , 随着使用的时间变长,陆陆续续使用了不少的软件, 更新了不少的软件包. 导致了现在ubuntu 系统反应速度严重下降. 下面是几种清理linux系统下冗余垃圾的命令, ...
- Python爬虫框架Scrapy实例(三)数据存储到MongoDB
Python爬虫框架Scrapy实例(三)数据存储到MongoDB任务目标:爬取豆瓣电影top250,将数据存储到MongoDB中. items.py文件复制代码# -*- coding: utf-8 ...