一、面向对象(上延续版)
1、匿名对象
概念:即没有名字的对象
格式:new 类名();
匿名对象调用方法:new 类名().成员方法名();
好处:节省内存空间,在堆内产生,不需要从栈中开辟空间,使用完后立刻被jvm中的垃圾回收器回收
2、局部变量和成员变量的区别
1)代码位置
成员变量:类中,方法外
局部变量:一般在方法之内
2)内存中的位置
成员变量:堆内存中,和new有关
局部变量:占内存中,和方法有关
3)生命周期不同
成员变量:随从对象的创建而存在,对象创建完毕后会被jvm中的垃圾回收器回收
局部变量:随着方法的调用而存在,当方法使用结束而消失
4)初始值
成员变量:系统会给成员变量进行默认的初始化,String的初始值为null,int的初始值为0
局部变量:必须进行初始化赋值
3、this的认识
this:用来提供本类中地址值的引用、
举例:
public class Student {
private String name ; //姓名
public void setName(String name){
this.name = name ; //等号右边,指向该类(Student)的地址,等号左边为set接收的数据
}
public String getName(){
return name ;
}
}
4、一个类的成员方法
类的成员变量:描述这个类有哪些属性
类的成员方法:setXXX()/getXXX():赋值和获取值的方法
类的构造方法
1)这个方法名和类名相同
2)这个方法没有void
3)构造方法可以重载:分为有参/无参构造方法
构造方法的目的:为了方便成员相关数据进行初始化
注意:当一个类中没有构造方法的时候,系统会默认提供一个无参构造方法(不显示在代码中),但,如果系统中已经有了一个有参构造方法了,此时系统不会提供无参构造方法,需要自己手动输入一个无参构造方法
一个标准类的写法:
成员变量私有化
成员获取值和输出值的方法(setXXX()/getXXX())
提供有参/无参构造方法
public class Phone {
private String brand ; //品牌
private int price ; //价格
private String color ; //颜色
private String memoryCache ;//内存
//无参构造方法
public Phone() {
}
//有参构造方法
public Phone(String brand, int price, String color, String memoryCache) {
this.brand = brand;
this.price = price;
this.color = color;
this.memoryCache = memoryCache;
}
//对外的公共访问方法setXXX()/getXXX()
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getMemoryCache() {
return memoryCache;
}
public void setMemoryCache(String memoryCache) {
this.memoryCache = memoryCache;
}
//打电话
public void callPhone(String toName){
System.out.println(brand+"可以给"+toName+"打电话");
}
//发短信
public void sendMsg(String toName){
System.out.println("可以给"+toName+"发短信了...");
}
}
5、static关键字
定义:是一种属性的描述,可以是变量,可以是方法(静态的,静止的)
特点:
1)被静态修饰的随着类的加载而价值,优先于对象
2)不能和this一起使用
3)本身含义结束共享,公用;可以多个对象公用
静态的使用范围:静态只能访问静态。
6、代码块
分类:静态代码块,构造代码块,构造方法
优先级:静态代码块>构造代码块>构造方法
举例:
class Root {
static {
System.out.println("Root的静态初始化块");//1
}
{
System.out.println("Root的普通初始化块");//4
}
public Root() {
System.out.println("Root的无参数的构造器");//5
}
}
class Mid extends Root {
static {
System.out.println("Mid的静态初始化块");//2
}
{
System.out.println("Mid的普通初始化块");//6
}
public Mid() {
System.out.println("Mid的无参数的构造器");//7
}
public Mid(String msg) {
this();
System.out.println("Mid的带参数构造器,其参数值:" + msg);//8
}
}
class Leaf extends Mid {
static {
System.out.println("Leaf的静态初始化块");//3
}
{
System.out.println("Leaf的普通初始化块");// 9
}
public Leaf() {
super("hello");
System.out.println("Leaf的构造器");//10
}
}
public class LeafTest {
public static void main(String[] args) {
new Leaf();
}
}
二、面向对象(中)
1、继承
定义:将多个类的共性内容抽取出来,房子一个独立的类中,让这个类和其他类产生一种关系就叫做继承
格式:
class 父类名{
共性内容:姓名,年龄
父类中的方法setXXX/getXXX等
}
class 子类名 extends 父类名{}
继承的好处:
1)可以提高代码的复用性
2)可以提高代码的维护性
3)类与类的继承关系,是后面“多态”的前提条件
特点:
1)继承只能接受单继承,不能多继承
2)虽然不能多继承,但是可以多层继承
举例:
class A{
public void show1(){
System.out.println("第一继承");
}
}
class B extends A{
public void show2(){
System.out.println("第二继承");
}
}
class C extends B{
public void show3(){
System.out.println("第三继承");
}
}
public class ExtendsDemo {
public static void main(String[] args) {
C c = new C() ;
c.show3(); //c本身的方法
c.show2(); //寻找B的方法
c.show1(); //A的方法
}
}
2、重写
引入:子类在调用父类方法时有两种情况
情况一:子类方法和父类方法名不相同,可以分别直接调用;
情况二:子类方法和父类方法名相同时:权限修饰符,返回值类型,参数列表都一样时,如果主函数使用了该方法,则会发生子类方法将父类方法覆盖的情况--->方法重写
override
举例:
class A {
public void show(){
System.out.println("我是A");
}
}
class B extends A{
public void show(){
System.out.println("我是B");
}
}
public class Demo{
public static void main(String[] args) {
B b =new B();
b.show(); //此时父类和子类的方法名相同,则会出现子类方法将父类方法覆盖,输出应为:我是B
}
}
3、final关键字
本身含义:最终的,无法更改的
特点:
1)final可以修饰类,该类不能被继承
2)final可以修饰变量,此时这个变量是一个”常数“
3)final可以修饰成员方法,被修饰的方法不能被子类重写
class A {
final int a = 20;
public void show(){
int a =30;
}
}
class B extends A {
}
public class FinalDemo {
public static void main(String[] args) {
B b =new B();
b.show();
System.out.println(b.a);
}
}
三、面向对象(下)
1、多态
1.什么是多态
宏观角度:一个事务在不同时刻体现的状态不同
微观角度:具体对象在内存中的变化
2.多态的前提条件
1)必须有继承关系,无继承,不提多态
2)必须存在方法重写
3)必须存在父类引用子类对象
格式:
父类名 对象名 = new 子类名() ; //向上转型:使用的父亲的东西
3.多态的成员访问特点(很重要)
1)成员变量:编译看左,运行看左;
2)成员方法:编译看左,运行看右;
3)构造方法:多态的前提条件,有继承关系,跟继承一样,分层初始化先执行父类的构造方法,然后进行子类的构造方法
4.多态的弊端
当多态的前提条件满足后,出现了多态的弊端
无法调用子类的特有功能!
解决方法1,重新创建自己的子类对象
解决方法2,
向下转型:
格式:
前提必须向上转型Fu fu = new Zi() ;
Zi z = (Zi)fu ; //强转的语法
5.多态的好处
1)提高代码的复用性,由继承保证
2)提高代码的延展性,由多态保证
实例:
class Animal{
public void eat(){
System.out.println("动物都需要吃饭");
}
public void sleep(){
System.out.println("动物都需要休息");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗侧着睡");
}
public void lookDoor() {
System.out.println("狗看门");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫躺着睡");
}
public void catch() {
System.out.println("猫抓老鼠");
}
}
public class DuoTaiDemo {
public static void main(String[] args) {
Animal a = new Cat() ;
a.eat();
a.sleep();
Cat c =(Cat) a;
c.catch();
Animal a2 = new Dog() ;
a2.eat();
a2.sleep();
Dog d =(Dog) a2;
d.lookDoor();
}
}
2、抽象类
1.什么是抽象类?
定义:在一个类中,如果由抽象方法,这个类必须为抽象类
2.抽象的方法格式:
根据写方法的格式一样,加入一个关键字abstract,而且没有方法体{}
public abstract 返回值类型 方法名(空参/带参) ;
3.抽象类的特点
1)不能实例化(不能创建对象)
2)必须强制子类进行抽象方法重写
4.抽象类的成员特点:
1)成员变量:抽象类的成员变量可以是常量(被final自定义)/变量
2)成员方法:可以是抽象类方法也可以是非抽象类方法
3)构造方法:可以定义无参/有参
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 eat();
public abstract void sleep();
}
class Student extends Person{
private String sno;
public Student (){
}
public Student(String name, int age, String sno) {
super(name, age);
this.sno = sno;
}
public String getSno() {
return sno;
}
public void setSno(String sno) {
this.sno = sno;
}
@Override
public void eat() {
System.out.println(getName()+"喜欢吃辣条");
}
@Override
public void sleep() {
System.out.println(getName()+"在学校宿舍睡觉");
}
public void study(){
System.out.println(getName()+"说,我爱学习");
}
}
class Worker extends Person{
private String wno;
public Worker() {
}
public Worker(String name, int age, String wno) {
super(name, age);
this.wno = wno;
}
public String getWno() {
return wno;
}
public void setWno(String wno) {
this.wno = wno;
}
@Override
public void eat() {
System.out.println(getName()+"喜欢吃肉");
}
@Override
public void sleep() {
System.out.println(getName()+"在工地宿舍休息睡觉");
}
public void work(){
System.out.println(getName()+"说,我爱工作");
}
}
public class PersonTest {
public static void main(String[] args) {
Person p =new Student("张三",18,"学生001");
Student s = (Student) p;
System.out.println(p.getName()+"---"+p.getAge()+"---"+s.getSno());
p.eat();
p.sleep();
s.study();
System.out.println("--------------------------------------------");
Person p2 =new Worker("李四",29,"工人001");
Worker w = (Worker) p2;
System.out.println(p2.getName()+"---"+p2.getAge()+"---"+w.getWno());
p2.eat();
p2.sleep();
w.work();
}
}
3、接口
1.什么是接口?
接口体现的是事务的一种额外功能
2.格式
interface 接口名{ //命名规范和类名命名一样,见名知意 "大驼峰命名法"
只能为抽象方法
}
接口的子类----"子实现类"
class 子类名 implements 接口名{//实现类必须实现接口的抽象方法,否则报错
}
//接口比抽象类还抽象
2.特点
接口最大的特点:不能实例化
3.接口的成员特点
1)成员变量:只能是常量,存在默认修饰符:public static final
2)成员方法:之你呢个是抽象方法,存在默认修饰符:public abstract
3)构造方法:没有构造方法
实例:
interface Area {
void calculateArea();
}
class MyCircle implements Area{
private double radius;
public MyCircle() {
}
public MyCircle(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public void calculateArea() {
System.out.println("圆的面积为:"+(3.14*getRadius()*getRadius()));
}
}
class MyRectangle implements Area{
private double length;
private double width;
public MyRectangle() {
}
public MyRectangle(double length, double width) {
this.length = length;
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public void calculateArea() {
System.out.println("矩形的面积为"+(getLength()*getWidth()));
}
}
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
System.out.println("-----------圆形-------");
System.out.print("请输入圆的半径:");
double a = sc.nextDouble();
Area a1 =new MyCircle(a);
a1.calculateArea();
System.out.println("-----------矩形-------");
System.out.println("请输入矩形的长和宽:");
double b = sc.nextDouble();
double c = sc.nextDouble();
Area b2 =new MyRectangle(b,c);
b2.calculateArea();
}
}
四、对面向对象中的几个问题
1、关于Java中面向对象牵扯关系问题
Java中最基本的单位:类
类和类:继承关系 extends,Java中只支持单继承和多层继承,不支持多继承
类和接口:实现关系implement 一个类可以实现多个接口
接口与接口:继承关系 extends
2、 在使用多态是出现ClassCastException,说明了什么?
ClassCastException属于运行事情异常的一种:代表“类转换异常”
使用多态操作向下转型时使用不当,堆内存中信息和占内存信息没有父子关系
3、abstract不能和那些关键字使用
static:静态方法算不上方法重写
private:因为abstract需要被重写,所以不能私有
final:被final修饰的成员方法不能被重写,违背了抽象类的要求
4、super关键字,和this的关系
super:代表父类的空间标识(代表父类的地址值引用)
区别:
1)
this.变量名 访问本类的成员变量
super.变量名 访问父类的成员变量
2)
this.方法名() 访问本类的成员方法
super.方法名() 访问父类的成员方法
3)
this() 访问本类无参构造方法
super() 访问父类的无参构造方法
4)
this(xxx) 访问本类的有参构造方法
super(xxx) 访问父类的有参构造方法
5、接口和抽象类的区别
从定义来说:
this:用来提供本类中地址值的引用
super:用来提供空间上的地址值(即,父类的地址值的引用)
区别:
成员变量: 抽象类:可以是变量,也可以是自定义常量
接口: 成员变量只能是常量.
成员方法 :抽象类: 抽象方法/非抽象方法
接口:只能是抽象方法
构造方法: 抽象类 :无参构造,有参构造都可以存在 存在继承关系,分层初始化
接口:无构造方法.
抽象类用 entends接口用implements
6、什么是方法重写 ,什么是方法重载
方法重写:出现在继承中,描述子类继承父类时,当父类方法与子类方法名重名时,子类方法将覆盖掉父类方法
方法重载:方法定义的时候,方法名相同,参数列表不同,与返回值无关,
7、方法的形式参数如果是引用类型和基本类型
为基本类型时:只需要在括号内输入基本类型数值即可
为引用类型时:需要传递是当前类的具体类对象