第五章 JAVA面向对象进阶
DAY9
- 继承
- 使用extends关键字。extends的英文意思是“扩展”,子类是父类的扩展。如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object
- Java中只有单继承,没有像C++那样的多继承
- Java中类没有多继承,接口有多继承
- 子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)
- instanceof 运算符:二元运算符,左边是对象,右边是类。当对象是右面类或子类所创建对象时,返回true;否则,返回false。
package cn.sxt.oo;
public class TestExtends {
public static void main(String[] args) {
Student student = new Student("quan",171,"cv");
student.study();
student.rest();
System.out.println(student instanceof Student);
System.out.println(student instanceof Person);
System.out.println(student instanceof Object);
}
}
class Person{
String name;
int height;
public void rest(){
System.out.println("休息一会~");
}
}
class Student extends Person{
String major;
public Student(String name,int height,String major) {
this.name = name;
this.height = height;
this.major = major;
}
public void study() {
System.out.println("学习啦~");
}
}
-
方法的重写override
- 子类通过重写父类的方法,可以用自身的行为替换父类的行为
- “==”: 方法名、形参列表相同
- “≤”:返回值类型和声明异常类型,子类小于等于父类
- “≥”: 访问权限,子类大于等于父类
-
Object类是所有Java类的根基类,也就意味着所有的Java对象都拥有Object类的属性和方法
- Object类中定义有public String toString()方法,其返回值是 String 类型。Object类中toString方法的源码为:
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
- toString()方法重写
public class TestObject {
public static void main(String[] args) {
TestObject to = new TestObject();
System.out.println(to);
System.out.println(to.toString());//与上一行相等
}
public String toString() {
return "测试";
}
}
- ==和equals方法
public class TestEquals {
public static void main(String[] args) {
Object obj;
String str;
User user1= new User(001,"quan","1234");
User user2= new User(001,"quanquan","1234");
System.out.println(user1 == user2); //false
System.out.println(user1.equals(user2)); //ture(User类对equals进行了重写)
String str1 = new String("sxt");
String str2 = new String("sxt");
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//ture(String类对equals进行了重写,可按住Ctrl键点击String查看其源码)
}
}
class User {
int id;
String name;
String pwd;
public User(int id, String name, String pwd) {
super();
this.id = id;
this.name = name;
this.pwd = pwd;
}
// 系统自动添加,可有可无
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
//右键 -> source -> Generage hashCode() and equals()...
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (id != other.id)
return false;
return true;
}
}
-
super关键字
-
super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。
使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。
-
构造方法第一句总是:super(…),来调用父类对应的构造方法。所以,流程就是:先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。
注:静态初始化块调用顺序,与构造方法调用顺序一样。
-
-
封装
- private 表示私有,只有自己类能访问
- default表示没有修饰符修饰,只有同一个包的类能访问
- protected表示可以被同一个包的类以及其他包中的子类访问
- public表示可以被该项目的所有包中的所有类访问
修饰符 | 同一个类 | 同一个包 | 子类 | 所有类 |
---|---|---|---|---|
private | * | |||
default | * | * | ||
protected | * | * | * | |
public | * | * | * | * |
-
封装的使用细节
-
一般使用private访问权限
-
提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作。(注意:boolean变量的get方法是is开头!) 只有get/set方法的类称之为JavaBean。
右键 -> 点击source(快捷键:Alt+Shift+S)->Generage Getters and Setters…
-
一般工作中类中的其他方法用public修饰,除非确定只用于本类。
-
-
多态
- 多态是方法的多态,不是属性的多态(多态与属性无关)
- 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象
- 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了
-
对象的转型
- 父类引用指向子类对象,我们称这个过程为向上转型,属于自动类型转换
- 向上转型后的父类引用变量只能调用它编译类型的方法,不能调用它运行时类型的方法。这时,我们就需要进行类型的强制转换,我们称之为向下转型!
-
final关键字
- 修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。
- 修饰方法:该方法不可被子类重写。但是可以被重载!
- 修饰类: 修饰的类不能被继承。比如:Math、String等。
接下来介绍一点数组的知识(第七章),并练习J20飞机大战游戏(第十三章)
DAY12
-
抽象方法和抽象类
- 抽象方法:使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现
- 抽象类:包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用
- 有抽象方法的类只能定义成抽象类
- 抽象类不能实例化,即不能用new来实例化抽象类
- 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。
- 抽象类只能用来被继承,抽象方法必须被子类实现
-
接口
[访问修饰符] interface 接口名 [extends 父接口1,父接口2…] { 常量定义; 方法定义; }
- 访问修饰符:只能是public或默认;接口名:和类名采用相同命名机制;extends:接口可以多继承
- 常量:接口中的属性只能是常量(名字最好大写),总是:public static final 修饰。不写也是。
- 方法:接口中的方法只能是:public abstract。 省略的话,也是public abstract。
-
JAVA类没有多继承(extends),但JAVA接口有多继承(implements)
-
内部类
- 内部类可以使用public、default、protected 、private以及static修饰
- 在Java中内部类主要分为成员内部类(非静态内部类、静态内部类)、匿名内部类、局部内部类
-
非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)
- 非静态内部类必须寄存在一个外部类对象里。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象
- 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员
- 非静态内部类不能有静态方法、静态属性和静态初始化块
- 外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例
public class TestInnerClass {
public static void main(String[] args) {
//创建内部类对象
Outer.Inner inner = new Outer().new Inner();
inner.show();
}
}
class Outer {
private int age = 10;
class Inner {
public void show() {
System.out.println("外部类的 成员变量age:"+Outer.this.age);
}
}
}
- 静态内部类
- 当一个静态内部类对象存在,并不一定存在对应的外部类对象。 因此,静态内部类的实例方法不能直接访问外部类的实例方法
- 静态内部类看做外部类的一个静态成员。 因此,外部类的方法中可以通过:“静态内部类.名字”的方式访问静态内部类的静态成员,通过 new 静态内部类()访问静态内部类的实例
- 匿名内部类:适合那种只需要使用用一次的类。比如:键盘监听操作等等。
new 父类构造器(实参类表) \实现接口 () {
//匿名内部类类体!
}
-
局部内部类:它是定义在方法内部的,作用域只限于本方法
-
API文档
- API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
- API文档是一个技术内容交付文件,包含如何有效地使用和集成api的说明。它是一个简明的参考手册,包含了使用API所需的所有信息,详细介绍了函数、类、返回类型、参数等,并有教程是示例支撑。
- 在线阅读,可选择SE版本
- 下载地址
- 中文版下载
-
String类常用的方法
public class StringTest1 {
public static void main(String[] args) {
String s1 = "core Java";
String s2 = "Core Java";
System.out.println(s1.charAt(3));//提取下标为3的字符
System.out.println(s2.length());//字符串的长度
System.out.println(s1.equals(s2));//比较两个字符串是否相等
System.out.println(s1.equalsIgnoreCase(s2));//比较两个字符串(忽略大小写)
System.out.println(s1.indexOf("Java"));//字符串s1中是否包含Java
System.out.println(s1.indexOf("apple"));//字符串s1中是否包含apple
String s = s1.replace(' ', '&');//将s1中的空格替换成&
System.out.println("result is :" + s);
}
}
public class StringTest2 {
public static void main(String[] args) {
String s = "";
String s1 = "How are you?";
System.out.println(s1.startsWith("How"));//是否以How开头
System.out.println(s1.endsWith("you"));//是否以you结尾
s = s1.substring(4);//提取子字符串:从下标为4的开始到字符串结尾为止
System.out.println(s);
s = s1.substring(4, 7);//提取子字符串:下标[4, 7) 不包括7
System.out.println(s);
s = s1.toLowerCase();//转小写
System.out.println(s);
s = s1.toUpperCase();//转大写
System.out.println(s);
String s2 = " How old are you!! ";
s = s2.trim();//去除字符串首尾的空格。注意:中间的空格不能去除
System.out.println(s);
System.out.println(s2);//因为String是不可变字符串,所以s2不变
}
}
作业
一、1.AB 2.A 3.D 4.B 5.ADC
三、参考
package cn.sxt.oo;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
Scanner scanner1 = new Scanner(System.in);
System.out.print("输入圆柱的半径:");
float r = scanner1.nextFloat();
Scanner scanner2 = new Scanner(System.in);
System.out.print("输入圆柱的高:");
float h = scanner1.nextFloat();
Cylinder cylinder = new Cylinder();
cylinder.setHight(h);
cylinder.showVolume(cylinder.getVolume(r));
}
}
class Circle{
private float radius;
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
}
public Circle() {
super();
}
public Circle(float radius) {
super();
this.radius = radius;
}
public double getArea(float radius) {
return Math.PI*radius*radius;
}
public double getPerimeter(float radius) {
return 2*Math.PI*radius;
}
public void show(float radius,double area ,double perimeter) {
System.out.println("圆的半径为"+radius);
System.out.println("圆的周长为"+perimeter);
System.out.println("圆的面积为"+area);
}
}
class Cylinder extends Circle{
private float hight;
public float getHight() {
return hight;
}
public void setHight(float hight) {
this.hight = hight;
}
public Cylinder() {
super();
}
public double getVolume(float radius) {
return hight*getArea(radius);
}
public void showVolume(double volume) {
System.out.println("圆柱的体积为"+volume);
}
}
package cn.sxt.oo;
public class Test2 {
public static void main(String[] args) {
TestInstrument testInstrument = new TestInstrument();
Erhu i = new Erhu();
testInstrument.test("quanquan", i);
}
}
class TestInstrument{ //测试类
public void test(String name,Instrument i) {
System.out.println("音乐家名字:"+name);
Musician musician = new Musician();
musician.play(i);
}
}
class Musician{ //音乐家类
public void play(Instrument i) {
i.makeSound();
}
}
class Instrument{ //乐器类
public void makeSound() {
System.out.println("music");
};
}
class Erhu extends Instrument{
public void makeSound() {
System.out.println("erhu");
}
}
class Piano extends Instrument{
public void makeSound() {
System.out.println("piano");
}
}
class Violin extends Instrument{
public void makeSound() {
System.out.println("violin");
}
}
package cn.sxt.oo;
public class Test3 {
public static void main(String[] args) {
YiRen person = new YiRen();
System.out.println("大家好,我是杨幂");
person.moive();
person.tvSeries();
person.sing();
}
}
interface Moive{
void moive();
}
interface TvSeries{
void tvSeries();
}
interface Sing{
void sing();
}
class YiRen implements Moive,TvSeries,Sing{
public void moive() {
System.out.println("我能演电影");
}
public void tvSeries() {
System.out.println("我能演电视剧");
}
public void sing() {
System.out.println("我能唱歌");
}
}