How to prevent null foreign key during database normalization?
NOTE

Many-to-Many relationships are represented by a linking table.

You are missing the link between Student(s) and Class(es)

create class_enrollment (
  student_id int not null references Student( id ),
  class_id   int not null references Class( id ),
  constraint class_enrollment_pk primary key ( student_id, class_id )
);


Adjustment

Your Grades table can then be modified to reference the PK of class_enrollment.

create table GRADES (
  student_id  int,
  class_id    int,
  category_id int,
  grade_val    number,
  constraint grade_pk primary key
     (student_id, class_id, category_id), -- a surrogate key is recommended
  constraint grade_fk1 foreign key (student_id, class_id)
     references class_enrollment(student_id, class_id)
);


Overall Grade

If you can always calculate a Summary value, You can hide the calculation in a VIEW (or a MATERIALIZED VIEW).

But, since teachers can override the calculated value, you'll want to store the Summary in the "parent table".

In your case, the "parent table" to Grades would be Class_Enrolement.

alter table class_enrollment add ( overall_grade  number );